当前位置: 首页 > 面试题库 >

是否将在n个多个DOM节点上调用angular.bootstrap实例化n个AngularJS应用程序?

苏季同
2023-03-14
问题内容

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

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


问题答案:

它将创建一个新的Angular
注入器服务实例,该实例负责依赖项注入并控制应用程序生命周期。因此,它也创造了其在应用中使用的服务的新实例(包括来自那些ng模块:$rootScope$compile,等)。

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

该不同的东西angular.bootstrapangular.injector(后者只是创建一个新的喷射器实例)是它连接的喷射器实例借助于到DOM元素$rootElement的服务。这样,此元素及其子元素与特定的喷射器实例相关联(可以使用获取angular.element(someElement).injector())。

无法在自举的元素(或其子元素)上引导应用程序,Angular
会保护它免受混乱。

但是,Angular并不是真正的傻瓜,可以通过反向引导应用程序来完成:

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

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

绕过用于双重引导的Angular防呆旁路非常简单。由于Angular使用继承的数据以分层方式获取元素的注入器(当element.data('$injector')在自举元素上未定义时,会自动从父级中检索它),因此必须将其覆盖:

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

现在,可以以任何顺序安全地引导应用程序了。但是app远离的问题<nested- app-container>仍然存在。可以通过将标记nestedAppContainer指令作为终端来解决

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

或通过将嵌套应用放入影子DOM中

nestedAppContainer = nestedAppContainer.createShadowRoot();

它专门用于隔离DOM部件(Chrome本身支持并在其他浏览器中多填充)。

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

如此处所示:

  <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);
    }
  };
});

虽然看起来很整洁,但请小心进行。就像其他任何利用未公开文档的黑客一样,该黑客可能掩盖了不利的副作用或被新的框架版本所破坏。

可能需要黑客攻击的案例并不多。大多数时候,如果您有与框架打交道的冲动,那就错了。



 类似资料:
  • 问题内容: 到目前为止,我以前一直认为Web应用程序只能具有我们在 我这样想对吗? 我可以在一个Web应用程序中拥有多个调度程序Servlet吗?如果是,如何? 在什么情况下我们可能需要这样做? 整个Web应用程序中只能有一个应用程序上下文吗? 我们如何定义多个应用程序上下文? 非Spring应用程序中可以存在吗? 问题答案: 一个Web应用程序中可以有多个调度程序servlet吗? Web应用程

  • 我有一个图像,我想在鼠标移动到某些矩形区域时显示工具提示。矩形区域可以达到1000。但是,只要检查每个矩形中的点是否在其中,即O(N),就会使界面在移动鼠标时没有响应。 有没有小于O(N)的方法?我可以预先对矩形进行排序(我假设这是必需的)。矩形可能会(很少)重叠,但同一区域重叠的矩形不能超过4-5个。在这种情况下,我可能需要获得所有矩形的列表,但即使只是其中的任何一个也足够了。 但是我假设这个问

  • 问题内容: 使用标准列表,我尝试选择最后2个列表项。我有多种排列方式,但似乎没有什么可以选择最后2种: 我知道类似CSS3的新选择器,但如果可能的话,我更喜欢一些可以在更多浏览器中使用的选择器(不必特别在意IE)。 问题答案: 这将选择列表的最后两个项目:

  • 我最近正在评估图形数据库或任何其他数据库的一个特定要求: 通过一个查询中节点的直接子节点及其所有直接和间接子节点的聚合属性检索每个节点的前n个子节点的能力。结果应返回正确的层次结构。 实例 < code >每个节点都有一个属性,即它有多少个直接子节点。并且该树不超过8层。假设我想运行整个树的查询,通过每个级别的所有节点,它的前2个子节点有最多的直接和间接子节点。它将为我们提供以下信息: 我想知道是

  • 问题内容: 我想防止在Java中启动应用程序的多个实例。我知道两种方法: 锁定文件 锁紧插座 但是,哪一个是更有效且更易于使用的呢?我应该使用哪一个? 同样欢迎任何其他解决方案。 问题答案: 编辑:我尝试使用Win200864b(版本不重要)和JFrame并通过JFrame在SystemTray中移动到Front()或图标化。DO_NOTHING_ON_CLOSE