我强烈建议阅读这篇文章:
与提供商的模块
当您导入模块时,通常使用对模块类的引用:
@NgModule({
providers: [AService]
})
export class A {}
-----------------------------------
@NgModule({
imports: [A]
})
export class B
通过这种方式,所有提供者都在模块上注册A
将被添加到根注入器并可用于整个应用程序。
但是还有另一种方法可以向提供者注册模块,如下所示:
@NgModule({
providers: [AService]
})
class A {}
export const moduleWithProviders = {
ngModule: A,
providers: [AService]
};
----------------------
@NgModule({
imports: [moduleWithProviders]
})
export class B
这与前一个具有相同的含义。
您可能知道延迟加载的模块有自己的注入器。所以假设你想注册AService
可用于整个应用程序,但有些BService
仅适用于延迟加载的模块。您可以像这样重构您的模块:
@NgModule({
providers: [AService]
})
class A {}
export const moduleWithProvidersForRoot = {
ngModule: A,
providers: [AService]
};
export const moduleWithProvidersForChild = {
ngModule: A,
providers: [BService]
};
------------------------------------------
@NgModule({
imports: [moduleWithProvidersForRoot]
})
export class B
// lazy loaded module
@NgModule({
imports: [moduleWithProvidersForChild]
})
export class C
Now BService
仅适用于子延迟加载模块并且AService
将可用于整个应用程序。
您可以将上面的内容重写为导出模块,如下所示:
@NgModule({
providers: [AService]
})
class A {
forRoot() {
return {
ngModule: A,
providers: [AService]
}
}
forChild() {
return {
ngModule: A,
providers: [BService]
}
}
}
--------------------------------------
@NgModule({
imports: [A.forRoot()]
})
export class B
// lazy loaded module
@NgModule({
imports: [A.forChild()]
})
export class C
###这与 RouterModule 有什么关系?
假设它们都使用相同的令牌进行访问:
export const moduleWithProvidersForRoot = {
ngModule: A,
providers: [{provide: token, useClass: AService}]
};
export const moduleWithProvidersForChild = {
ngModule: A,
providers: [{provide: token, useClass: BService}]
};
根据您的要求提供单独的配置token
从延迟加载的模块中你会得到BService
正如计划。
Router模块使用ROUTES
令牌来获取特定于模块的所有路由。由于它希望特定于延迟加载模块的路由在此模块内可用(类似于我们的 BService),因此它对延迟加载子模块使用不同的配置:
static forChild(routes: Routes): ModuleWithProviders {
return {
ngModule: RouterModule,
providers: [{provide: ROUTES, multi: true, useValue: routes}]
};
}