我在子模块中有一个服务,它包装了一些第三方模块,实例化并初始化它的服务以准备在应用程序中使用。
@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_INITIALIZER
与 config
block 也有一些相同的特征,因为它用于在组件初始化之前配置服务并且容易受到竞争条件的影响(例如,因为 APP_INITIALIZER
用于配置Router
,将其注入(inject)到另一个APP_INITIALIZER
会导致循环依赖。
关于javascript - 在 Angular 2 子模块中强制服务实例化(AngularJS 运行 block 的替代方案),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39801701/