我想知道如何在导入模块时不进行任何手动服务注入和运行就如何从模块中运行服务,就像RouterModule
一样。
@NgModule({
imports: [
BroserModule,
MyModuleWithServicesThatShouldAutoRun,
]
})
export class AppModule { }
答案 0 :(得分:1)
免责声明:这是基于another answer的,因为没有更简单的方法可以执行OP所需的操作,因此未被接受为正确答案。
您可以使用APP_INITIALIZER
注入令牌在运行任何其他应用程序代码之前运行初始化代码。
APP_INITIALIZER
在@angular/core
中定义,您可以这样包含它:
import { APP_INITIALIZER } from '@angular/core';
APP_INITIALIZER
是OpaqueToken
,它引用了
multi provider ApplicationInitStatus
服务。它支持多种依赖关系,您可以在提供商列表中多次使用它,例如:
@NgModule({
providers: [
MyService,
{
provide: APP_INITIALIZER,
useFactory: (service: MyService) => function() { return service.init(); },
deps: [MyService],
multi: true
}]
})
export class AppModule { }
此提供程序声明正在告诉ApplicationInitStatus
类运行MyService.init()
方法。 init()
返回Promise
,而ApplicationInitStatus
阻止应用启动,直到Promise
解析为止。
export class MyService {
// omitted other methods for brevity
init(): Promise<any> {
// start some observers, do the stuff you need
// you can even request something via http
return this.httpClient
.get('https://someurl.com/example')
.toPromise()
}
}
这样,init中的所有内容都会运行并阻止应用程序加载,直到Promise
解析为止。
请注意,无论init()
方法花费多长时间,这都会增加您应用的前期加载时间。要在打开路线之前加载内容,请改用resolver。
来源:
答案 1 :(得分:0)
RouterModule
的用途是使用forRoot()
和forChild()
(有时称为forFeature()
)方法,这是在模块加载时进行配置的惯例。有关here的详细说明,请参见。
如果您查看RouterModule
's source code,您会发现forRoot()
和forChild()
像下面这样配置模块:
providers: [
ROUTER_PROVIDERS,
provideRoutes(routes),
{
provide: ROUTER_FORROOT_GUARD,
useFactory: provideForRootGuard,
deps: [[Router, new Optional(), new SkipSelf()]]
},
// many more, omitted
]
在该位置,您还可以按照其他答案中的说明添加APP_INITIALIZER
,这将有效地使您的导入模块看起来像这样:
@NgModule({
imports: [
BroserModule,
MyModuleWithServicesThatShouldAutoRun.forRoot( /* some config, maybe */),
]
})
export class AppModule { }