javascript - 在 Angular 2 子模块中强制服务实例化(AngularJS 运行 block 的替代方案)

标签 javascript angular typescript angular2-services

我在子模块中有一个服务,它包装了一些第三方模块,实例化并初始化它的服务以准备在应用程序中使用。

@Injectable()
class SubmoduleInitializerService {
    constructor (thirdPartyService: ThirdPartyService) {
      thirdPartyService.initialize(...);
      ...
    }
}

@NgModule({
    imports: [ThirdPartyModule],
    exports: [ThirdPartyModule],
    providers: [
        ThirdPartyService,
        SubmoduleInitializerService
    ]
})
class AppSubmodule {}

ThirdPartyService 不是直接注入(inject)app,而是被其他ThirdPartyModule 单元使用,所以只要注入(inject)SubmoduleInitializerService注入(inject)器作为 ThirdPartyService 或父注入(inject)器,一切正常:

export class AppComponent {
    constructor(
      /* DO NOT REMOVE! BAD THINGS HAPPEN! */
      submoduleInitializerService: SubmoduleInitializerService
    ) {}
    ...
}

它被证明是一个糟糕的模式,因为如果 SubmoduleInitializerService 既没有在类中也没有在模板中使用(不小心已删除一次)。

基本上 AppSubmodule 模块需要 Angular 1.x angular.module(...).run(...) block 的替代方案。

这里有哪些选项?

最佳答案

APP_INITIALIZER (未记录的)服务在 Angular 2 中很好地扮演了 AngularJS 配置/运行 block 的 Angular 色(不包括异步初始化的特性)。

对于只是热切实例化 SubmoduleInitializerService 的 noop 初始化 block ,它是:

@NgModule({
    imports: [ThirdPartyModule],
    exports: [ThirdPartyModule],
    providers: [
        ThirdPartyService,
        SubmoduleInitializerService,
        {
            provide: APP_INITIALIZER,
            useFactory: () => () => {},
            deps: [SubmoduleInitializerService],
            multi: true
        }
    ]
})
class AppSubmodule {}

由于 APP_INITIALIZER 是多 vendor ,它允许每个应用程序有多个初始化函数,这些函数遵循模块的加载顺序。

对于同步初始化,更短(可能更合适)的替代方法是将服务注入(inject)模块的构造函数:

@NgModule({
    imports: [ThirdPartyModule],
    exports: [ThirdPartyModule],
    providers: [
        ThirdPartyService,
        SubmoduleInitializerService
    ]
})
class AppSubmodule {
    constructor(sis: SubmoduleInitializerService) {}
}

this answer 中所述, APP_INITIALIZERconfig block 也有一些相同的特征,因为它用于在组件初始化之前配置服务并且容易受到竞争条件的影响(例如,因为 APP_INITIALIZER用于配置Router,将其注入(inject)到另一个APP_INITIALIZER会导致循环依赖。

关于javascript - 在 Angular 2 子模块中强制服务实例化(AngularJS 运行 block 的替代方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39801701/

相关文章:

javascript - 如何在没有 eval 的情况下编写这段 JavaScript 代码?

javascript - 将 UTC 时间转换为本地时间( Angular )

javascript - Angular 2 最终版本中的提供程序更改

javascript - 从 'angularfire2/database' 导入 {AngularFireDatabase, FirebaseListObservable}

angular - 将输入值传递给对话框组件

javascript - 如何在解构时检查对象 prop 是否存在?

javascript - 如果单击了第一个按钮,则只能单击第二个按钮

javascript - 使用 jQuery 检测元素内容变化

angular - 既然 ProvideIn 是一个选项,那么 CoreModule 模式是否有理由?

node.js - 如何使用 Typescript Express 应用程序渲染 Lit Element Web 组件?