如何在功能模块层次结构中使用 .forRoot()
How to use .forRoot() within feature modules hierarchy
任何人都可以向我说明我应该如何使用 .forRoot()
调用构建多个嵌套功能模块层次结构?
例如,如果我有这样的模块怎么办:
- MainModule
- SharedModule
- FeatureModuleA
- FeatureModuleA1
- FeatureModuleA2
- FeatureModuleB
所有功能模块都有一个 .forRoot()
静态函数。
我应该如何定义 FeatureModuleA 并以某种方式“转移”.forRoot()
函数?
@NgModule({
imports: [
//- I can use .forRoot() calls here but this module not the root module
//- I don't need to import sub-modules here, FeatureA only a wrapper
//FeatureModuleA1.forRoot(), //WRONG!
//FeatureModuleA2.forRoot(), //WRONG!
],
exports: [
//I cannot use .forRoot() calls here
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureModuleA {
static forRoot(): ModuleWithProviders {
return {
//At this point I can set any other class than FeatureModuleA for root
//So lets create a FeatureRootModuleA class: see below!
ngModule: FeatureModuleA //should be: FeatureRootModuleA
};
}
}
我可以创建另一个 class 供 root 使用,然后在 FeatureModuleA 的 forRoot()
函数中设置它:
@NgModule({
imports: [
//Still don't need any sub module within this feature module
]
exports: [
//Still cannot use .forRoot() calls but still need to export them for root module too:
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureRootModuleA { }
But how can I "transfer" .forRoot()
calls within this special ModuleClass?
如我所见,我需要将所有子模块直接导入我的根 MainModule 并为每个子模块调用 .forRoot()
:
@NgModule({
imports: [
FeatureModuleA1.forRoot(),
FeatureModuleA2.forRoot(),
FeatureModuleA.forRoot(),
SharedModule.forRoot()
]
})
class MainModule { }
我说得对吗?在你回答之前,请看一下这个文件:
https://github.com/angular/material2/blob/master/src/lib/module.ts
据我所知,这个 repo 由 angular 官方团队维护。因此,他们通过在特殊的 MaterialRootModule 模块中导入所有 .forRoot()
调用来解决上述问题。我真的不明白如何将它应用于我自己的根模块? root 和 .forRoot 在这里的真正含义是什么?那是相对于包而不是实际的 web 项目?
一般forRoot
用于添加application/singleton服务
@NgModule({
providers: [ /* DONT ADD HERE */ ]
})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [ AuthService ]
}
}
}
原因是,如果您将AuthService
添加到@NgModule
中的providers
,如果您导入[=16=,则可能会创建多个] 进入其他模块。
我不是 100% 清楚当 SharedModule
被导入一个急切加载的模块时是否会创建服务,但是提到的文档的解释是关于延迟加载模块的。当您延迟加载模块时,将创建所有提供程序。
出于这个原因,我们添加了一个(按照惯例)forRoot
方法来表示该方法只应为根(app)模块调用,而对于其他模块,它应该正常导入
@NgModule({
imports: [SharedModule]
})
class FeatureModule {}
@NgModule({
imports: [SharedModule.forRoot()]
})
class AppModule {}
由于 forRoot
仅用于提供单例服务,您可以 "re-provide" 在 SharedModule
:
@NgModule({})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
AuthService,
FeatureModuleA.forRoot().providers,
FeatureModuleB.forRoot().providers,
],
}
}
}
这样一来,所有的服务都将由 SharedModule
本身提供(而不是由各自的 sub-module)提供,但似乎没有关系。也许有人可以争论...
请注意,FeatureModuleA
也可以通过其 sub-module 类似的方式 "re-provide" 单例服务。
如上所述,延迟加载模块很重要,因为可以在延迟加载模块中使用共享服务,但如果该服务已被另一个模块使用和实例化,则将有两个实例,因此需要单例模式。 AuthService 在这里是一个很好的例子 - 您不希望有一个服务实例具有未经身份验证的用户,而另一个具有 "the same" 用户身份验证。
Angular6 的新增功能有一种将提供程序注册为单例的新方法。在服务的 @Injectable() 装饰器中,使用 providedIn 属性。将其值设置为 'root'。然后你不需要将它添加到根模块的提供者列表中,或者在这种情况下你也可以像这样将它设置到你的 SharedModule 中:
@Injectable({
providedIn: SharedModule // or 'root' for singleton
})
export class AuthService {
...
任何人都可以向我说明我应该如何使用 .forRoot()
调用构建多个嵌套功能模块层次结构?
例如,如果我有这样的模块怎么办:
- MainModule
- SharedModule
- FeatureModuleA
- FeatureModuleA1
- FeatureModuleA2
- FeatureModuleB
所有功能模块都有一个 .forRoot()
静态函数。
我应该如何定义 FeatureModuleA 并以某种方式“转移”.forRoot()
函数?
@NgModule({
imports: [
//- I can use .forRoot() calls here but this module not the root module
//- I don't need to import sub-modules here, FeatureA only a wrapper
//FeatureModuleA1.forRoot(), //WRONG!
//FeatureModuleA2.forRoot(), //WRONG!
],
exports: [
//I cannot use .forRoot() calls here
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureModuleA {
static forRoot(): ModuleWithProviders {
return {
//At this point I can set any other class than FeatureModuleA for root
//So lets create a FeatureRootModuleA class: see below!
ngModule: FeatureModuleA //should be: FeatureRootModuleA
};
}
}
我可以创建另一个 class 供 root 使用,然后在 FeatureModuleA 的 forRoot()
函数中设置它:
@NgModule({
imports: [
//Still don't need any sub module within this feature module
]
exports: [
//Still cannot use .forRoot() calls but still need to export them for root module too:
FeatureModuleA1,
FeatureModuleA2
]
})
class FeatureRootModuleA { }
But how can I "transfer"
.forRoot()
calls within this special ModuleClass?
如我所见,我需要将所有子模块直接导入我的根 MainModule 并为每个子模块调用 .forRoot()
:
@NgModule({
imports: [
FeatureModuleA1.forRoot(),
FeatureModuleA2.forRoot(),
FeatureModuleA.forRoot(),
SharedModule.forRoot()
]
})
class MainModule { }
我说得对吗?在你回答之前,请看一下这个文件: https://github.com/angular/material2/blob/master/src/lib/module.ts
据我所知,这个 repo 由 angular 官方团队维护。因此,他们通过在特殊的 MaterialRootModule 模块中导入所有 .forRoot()
调用来解决上述问题。我真的不明白如何将它应用于我自己的根模块? root 和 .forRoot 在这里的真正含义是什么?那是相对于包而不是实际的 web 项目?
一般forRoot
用于添加application/singleton服务
@NgModule({
providers: [ /* DONT ADD HERE */ ]
})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [ AuthService ]
}
}
}
原因是,如果您将AuthService
添加到@NgModule
中的providers
,如果您导入[=16=,则可能会创建多个] 进入其他模块。
我不是 100% 清楚当 SharedModule
被导入一个急切加载的模块时是否会创建服务,但是提到的文档的解释是关于延迟加载模块的。当您延迟加载模块时,将创建所有提供程序。
出于这个原因,我们添加了一个(按照惯例)forRoot
方法来表示该方法只应为根(app)模块调用,而对于其他模块,它应该正常导入
@NgModule({
imports: [SharedModule]
})
class FeatureModule {}
@NgModule({
imports: [SharedModule.forRoot()]
})
class AppModule {}
由于 forRoot
仅用于提供单例服务,您可以 "re-provide" 在 SharedModule
:
@NgModule({})
class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
AuthService,
FeatureModuleA.forRoot().providers,
FeatureModuleB.forRoot().providers,
],
}
}
}
这样一来,所有的服务都将由 SharedModule
本身提供(而不是由各自的 sub-module)提供,但似乎没有关系。也许有人可以争论...
请注意,FeatureModuleA
也可以通过其 sub-module 类似的方式 "re-provide" 单例服务。
如上所述,延迟加载模块很重要,因为可以在延迟加载模块中使用共享服务,但如果该服务已被另一个模块使用和实例化,则将有两个实例,因此需要单例模式。 AuthService 在这里是一个很好的例子 - 您不希望有一个服务实例具有未经身份验证的用户,而另一个具有 "the same" 用户身份验证。
Angular6 的新增功能有一种将提供程序注册为单例的新方法。在服务的 @Injectable() 装饰器中,使用 providedIn 属性。将其值设置为 'root'。然后你不需要将它添加到根模块的提供者列表中,或者在这种情况下你也可以像这样将它设置到你的 SharedModule 中:
@Injectable({
providedIn: SharedModule // or 'root' for singleton
})
export class AuthService {
...