gpt4 book ai didi

javascript - 在 "n"多个 DOM 节点上调用 angular.bootstrap 会实例化 "n "AngularJS 应用程序吗?

转载 作者:行者123 更新时间:2023-12-02 15:35:50 26 4
gpt4 key购买 nike

调用 angular.bootstrap 将创建一个新的 AngularJS 实例,以及单独的摘要周期、根作用域、注入(inject)器等,这样说是否正确?

如果是这样,是否可以嵌套此类应用程序(即在由另一个 AngularJS 应用程序管理的 DOM 内部的 DOM 节点上调用 Bootstrap )? (我想不会!)

最佳答案

它将创建一个新的 Angular 实例 injector服务,负责dependency injection并控制应用程序生命周期。因此,它还会创建应用程序中使用的服务的新实例(包括 ng 模块中的实例: $rootScope$compile 等)。

您可能会将其视为应用程序的新实例(它是模块的集合)。 Angular 本身( angular 对象)未实例化。

不同之处 angular.bootstrap来自angular.injector (后者只是创建一个新的注入(inject)器实例)是它 links an injector instance通过 $rootElement 到 DOM 元素服务。这样,该元素及其子元素与特定的注入(inject)器实例相关联(可以通过 angular.element(someElement).injector() 获取)。

无法在引导元素(或其子元素)上引导应用程序,Angular will protect it以免被搞乱。

但是,Angular 并不是真的万无一失,它可以通过引导应用程序来完成 in reverse :

angular.bootstrap(nestedAppElement, ['nestedApp']);
angular.bootstrap(appElement, ['app']);

看来我们终于把事情搞砸了。没有什么可以阻止app<nested-app-container> 中编译自己的指令,并且它使用自己的注入(inject)器和作用域(这里是 app 根作用域)来编译它们,而不是属于当前 DOM 元素的作用域和注入(inject)器。如果嵌套应用程序将由某些父应用程序指令重新编译,事情会变得更加困惑。

绕过 Angular 的双重引导非常简单。由于 Angular 使用 inheritedData要以分层方式获取元素的注入(inject)器(当引导元素上未定义 element.data('$injector') 时,会自动从父元素中检索它),必须覆盖它:

angular.module('app').directive('nestedAppContainer', function () {
return {
compile: function (element) {
element.data('$injector', null);
}
};
});

现在是应用程序can be safely bootstrapped in any order 。但保留app的问题远离 <nested-app-container>仍然在那里。可以通过标记 nestedAppContainer 来解决指令作为终端

angular.module('app').directive('nestedAppContainer', function () {
return {
priority: 100000,
terminal: true,
...
};
});

或者将嵌套应用程序放入 shadow DOM

nestedAppContainer = nestedAppContainer.createShadowRoot();

专门用于隔离 DOM 部分(Chrome 原生支持,并在其他浏览器中进行了 polyfilled)。

<小时/>

TL;DR:Angular 中嵌套应用程序的解决方案

事实上shown here :

  <body>
<div app-dir>
<nested-app-container></nested-app-container>
</div>
</body>

var appElement = document.querySelector('body');

var nestedAppContainer = document.querySelector('nested-app-container');
// nestedAppContainer = nestedAppContainer.createShadowRoot();

var nestedAppElement = angular.element('<nested-app>')[0];
angular.element(nestedAppContainer).append(nestedAppElement);

angular.element(nestedAppElement)
.append('<div app-dir>(app-dir)</div>')
.append('<div nested-app-dir>(nested-app-dir)</div>');

angular.element().ready(function () {
angular.bootstrap(appElement, ['app']);
angular.bootstrap(nestedAppElement, ['nestedApp']);
});

angular.module('nestedApp', []).directive('nestedAppDir', function () {
return {
controller: function ($scope) {
$scope.app = 'nested app';
},
compile: function (element) {
element.prepend('nested app is "{{ app }}"');
}
}
});

angular.module('app', []).directive('appDir', function () {
return {
controller: function ($scope) {
$scope.app = 'app';
},
compile: function (element) {
element.prepend('app is "{{ app }}"');
}
}
});

angular.module('app').directive('nestedAppContainer', function () {
return {
priority: 100000,
// 'terminal' is redundant with nestedAppContainer.createShadowRoot()
terminal: true,
compile: function (element) {
// element injector is not 'undefined' anymore,
// so it won't be inherited from parent elements
element.data('$injector', null);
}
};
});

虽然它可能看起来很整洁,但请小心操作。与利用未记录内容的任何其他黑客一样,这一黑客可能会隐藏不利的副作用或被新框架版本破坏。

没有那么多可能需要黑客攻击的情况。大多数时候,你有一种想要对抗框架的冲动,但你做错了。

关于javascript - 在 "n"多个 DOM 节点上调用 angular.bootstrap 会实例化 "n "AngularJS 应用程序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32954346/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com