关于angular:关于-Angular-应用-Components-和-Directives-的实例化问题

7次阅读

共计 1347 个字符,预计需要花费 4 分钟才能阅读完成。

同 Angular Module 不同,Angular Components 和 Directives 要实例化屡次,每个呈现在 HTML template 中的 markup 都会对应一次实例化。

此外,这些项的 作用域 也限定在它们被导入的 NgModule 中,以避免两个组件应用雷同的选择器时产生命名抵触。因为依赖注入 (DI) 行为的这种差别,须要辨别一个蕴含组件和指令的 NgModule 和一个蕴含组件、指令和 providers 的 ModuleWithProviders 是很有帮忙的,这正是 forRoot()办法进行辨别的中央。

上面是 SAP Spartacus 对于 forRoot 办法的一个例子:

export class SiteContextModule {static forRoot(): ModuleWithProviders<SiteContextModule> {
    return {
      ngModule: SiteContextModule,
      providers: [provideDefaultConfigFactory(defaultSiteContextConfigFactory),
        contextServiceMapProvider,
        ...contextServiceProviders,
        ...siteContextParamsProviders,
        provideConfigValidator(baseSiteConfigValidator),
        {
          provide: CONFIG_INITIALIZER,
          useFactory: initSiteContextConfig,
          deps: [SiteContextConfigInitializer, SiteContextConfig],
          multi: true,
        },
        ...contextInitializerProviders,
      ],
    };
  }
}

然而,依赖注入并不总是这么简略。有些时候,应用程序的所有 ngmodule 在疏导过程中都不可用。提早加载就是这样一个例子。当在路由过程中惰性加载 NgModule 时,在惰性加载的 NgModule 中注册的提供商及其子模块在疏导过程中不可用,Angular 那时无奈注册它们。因而,它们只有在加载路由时才会被增加为提供商,而且它们的作用域会从惰性加载的 NgModule 及其子模块开始注入。如果有多个惰性加载 NgModule 试图注册雷同的提供商,那么 NgModule 树中的每个节点最终都会领有不同的实例。通过在根目录下导入提供商,它有助于确保所有惰性加载的 ngmodule 都能取得该提供商的同一个实例,这也是 forRoot() 被命名为该实例的起因。

总结

何时应用 Module 的 forRoot 办法?简言之,当一个库的 dependency 须要某个 module 时,就调用该 module 的 forRoot 办法,达到全局 (globally) 导入 providers 的目标。

在其余 ngmodule 中,必要时应用 import 的非根模式来导入组件和指令。

当一个个性 NgModule 导出的组件和指令须要共享雷同的自定义提供商实例时,请思考用 forRoot()办法在根 NgModule 中注册这些提供商。这有助于确保所有子 ngmodule 都能拜访雷同的提供商实例,而不须要使用者显式地解决提供商注册。

正文完
 0