将元素绑定到不同帧中的现有 AngularJS 作用域

Bind element to existing AngularJS scope in a different frame

本文关键字:AngularJS 作用域 绑定 元素      更新时间:2023-09-26

我有一个页面A,其中包含两个iFrame B和C。B和C都是受信任的,在我的控制之下。B和C都使用AngularJS。我想使用 B 页上内部元素的范围作为 C 页上元素的范围。

更具体地说,

页 A:

...
<iframe src="Page B"/>
<iframe src="Page C"/>
...

页 B:

...
<div id="trunk-element" ng-controller="PageBController">
  {{pageBModel.text}}
</div>
...

页 C:

...
<div id="grafted-element">
  {{pageBModel.text}}
</div>
...

如何让 #grafted 元素"承担"#trunk 元素的范围?也就是说,我希望 #grafted 元素的行为与它包含在 B 页上 #trunk 元素中完全相同。我在 C 页中引用了 #trunk 元素的范围。

我尝试过的一些东西:

覆盖 #grafted 元素的"$scope"数据属性。这将被还原。

在 C 页上创建一个控制器,我将$scope的$parent和__proto__属性替换为 #trunk 元素的范围。然后我 #grafted 元素包含在该控制器中。这有效,但是当页面BModel.text更改时,呈现不会更新。

我最终通过更全面地劫持控制器的范围来解决这个问题。具体说来:

用于页面 C 的 Javascript:

// copypasta from angular's $new
var adoptScope = function(parent, child) {
  child.$$listeners = {};
  child.$parent = parent;
  child.__proto__ = parent;
  child.$$watchers = null;
  child.$$nextSibling = null;
  child.$$childHead = null;
  child.$$childTail = null;
  child.$$prevSibling = parent.$$childTail;
  if (parent.$$childHead) {
    parent.$$childTail.$$nextSibling = child;
    parent.$$childTail = child;
  } else {
    parent.$$childHead = parent.$$childTail = child;
  }
  child.$root = parent.$root;
  child.$$asyncQueue = parent.$$asyncQueue;
  child.$$postDigestQueue = parent.$$postDigestQueue;
};
myApp.controller('ExternalCtrl', function($scope) {
  adoptScope(wScope, $scope);
});

以及页面 C 的 html:

...
<div ng-controller="ExternalCtrl">
  {{pageBModel.text}}
</div>
...

其中 wScope 是 #trunk 元素的角度范围。