Angular 2 惰性模块和共享模块单例

标签 angular

我正在使用 this 学习 angular2 的延迟加载和共享依赖项文章。我知道 lazy 模块有一个单独的依赖树,它不与 eager 模块共享相同的服务实例。

当我从惰性模块的导入部分删除 SharedModule 导入时,行为发生了变化,我在急切模块和惰性模块之间获得了单例服务。

根据文档,为了重用相同的共享服务,还有更多工作要做,如 this 中所述。文章 。但我可以通过从共享模块定义中删除导入来使其工作。有人可以解释这种行为

这是 plnkr

@NgModule({
  imports: [
    //SharedModule   //This is removed
    routing
  ],
  declarations: [LazyComponent]
})

最佳答案

延迟加载不会创建单独的依赖树 - 至少不会像您描述的那样。

您可能已经知道,Angular 的依赖项注入(inject)系统实际上是一棵注入(inject)器树 - 一个用于 View 层次结构中的每个组件。当你请求一个依赖项时,Angular 遍历这棵注入(inject)器树,从请求依赖项的组件开始,直到它找到第一个能够提供该依赖项的注入(inject)器。 如果需要,这会为您提供很多功能,因为在组件树的任何级别,您都可以为组件的依赖项指定一个提供者,并让该组件获得该依赖项自己的实例。此外,该组件的任何子组件也将共享相同的依赖实例。

这是关于组件的层次依赖注入(inject)如何工作的基本概要。然而,当涉及到模块时,情况就有些不同了。默认情况下,NgModule 提供的任何依赖项都会添加到根注入(inject)器中,这意味着该依赖项的单个实例将由整个应用程序共享。异常(exception)情况是 NgModule 是延迟加载的。在这种情况下,延迟加载模块提供的依赖项不会添加到根注入(inject)器中。相反,这些依赖项将被添加到延迟加载模块的根组件(我很难学到这一点 - 如果您的延迟加载模块有多个“根组件”,每个“根组件”将获得自己的实例依赖)。

因此,它仍然是相同的基本层次结构——只是预加载模块将它们的依赖项添加到根注入(inject)器,而惰性加载模块将它们的依赖项添加到它们模块的根组件。此外,如果延迟加载的模块导入了一个也提供依赖项的 NgModule(例如你的 SharedModule),这些依赖项也会被添加到模块的根组件中。 (请注意,如果 SharedModule 也是预加载的,它的依赖项也将被添加到根注入(inject)器 - 导致这些依赖项的多个实例可用)。

最后一点就是为什么您会看到您所看到的行为。当您的惰性模块导入 SharedModule 时,SharedModules 提供的依赖项会添加到惰性模块的根组件中 - 导致这些依赖项的重复实例。

关于Angular 2 惰性模块和共享模块单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43151993/

相关文章:

Angular 6 错误显示为 'mat-form-field' 不是已知元素 :

forms - 找不到模块 '@angular/forms'

angular - 在所有列上实现 NGX 数据表过滤

javascript - 在运行时在 Angular 中更改应用程序主题

angular - [attr.disabled] ="true"在 anchor 标记中不起作用

javascript - 将时刻格式化为字符串

javascript - 身份验证的架构和思考

angular - 操作已正确分派(dispatch),但 reducer 未被调用

angular2 检查用户是否通过身份验证

javascript - 在我的代码中添加这个包装器是什么?