Angular 中返回 ModuleWithProviders 的参数化函数
parametrized function returning ModuleWithProviders in Angular
我有一个由多个组件组成的应用程序,每个组件都定义了自己的路线状态子集。根据集成这些组件的应用程序,它们(app)提供父状态,某些组件状态应放置在父状态下。即
组件状态:
[{
name: 'component',
url: '/component',
component: ComponentRootComponent,
abstract: true,
default: '.list'
}, {
name: 'component.list',
url: '',
component: ComponentListComponent
},...]
这是一些应用部分模块:
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule,
UIRouterModule.forChild({
states: RouterUtil.setParentState(SECTION_STATES[0].name, SOME_COMPONENT_STATES)
})
]
})
export class AppSectionModule {}
setParentState()
函数只是遍历组件状态并在它们前面加上父状态名称前缀,因此它们低于特定的路由状态。
这一切都很棒,但与其为我的每个组件添加两个导入,我认为如果我为我的模块提供一个函数,允许我对每个组件有一个单一但可配置的导入会更好。
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule.importFor(SECTION_STATES[0].name)
]
})
export class AppSectionModule {}
importFor
因此应该 return ModuleWithProviders
类型,它是我的原始组件模块的包装器,它还应该定义组件路由并将其放置在特定的父路由下:
export class SomeComponentModule {
public static importFor(parentState: string): ModuleWithProviders {
return {
ngModule: SomeComponentModule,
providers: [
// what do I do here?
]
};
}
}
如何实现这样的功能?我不知道在这个功能中应该如何调用或提供UIRuterModule.forChild(...)
?这是我要解决的主要问题。
通过使用 "hidden" 模块,您可以完成此操作。
第一个模块有一个 forRoot() 或者在你的例子中有一个 importFor()
其中有一个指向隐藏模块的 ngModule。
这个模块是在调用 importFor 时导入的调用。
然后导入原始模块并将其导出以使其显示为隐藏。
我发现这是制作可重用模块的好方法,我可以简单地将这些模块放入我的项目中,所有东西都配置了 reducer、effects、routes 和所有 :)
@NgModule({
imports: [
SharedModule,
],
declarations: [
...SHARED_COMPONENTS,
],
exports: [
...SHARED_COMPONENTS,
]
})
export class SecurityModule {
// when the user imports SecurityModule.forRoot() in the app module what we really import is the RootSecurityModule
// but it will also create the IsAuthenticated guard
// it also imports all the feature stuff such as reducers, effects and routes
// if we then later on need to access shared components from the SecurityModule we can import the module without the forRoot()
static forRoot(): ModuleWithProviders {
return {
ngModule: RootSecurityModule,
providers: [
IsAuthenticatedGuard,
],
};
}
}
@NgModule({
imports: [
// import the above module so that we get all the shared declarations
SecurityModule,
// import the "include once" modules for security
StoreModule.forFeature('security', securityReducer),
EffectsModule.forFeature([
SecurityEffects
]),
SecurityRoutingModule,
],
// we need to export the SecurityModule otherwise SecurityModule.forRoot() will not mean the same thing as SecurityModule
exports: [
SecurityModule,
]
})
export class RootSecurityModule {}
检查 UIRouterModule 实际做了什么,这似乎按预期工作:
export class SomeComponentModule {
public static importBelowState(parentState: string): ModuleWithProviders {
return {
ngModule: SomeComponentModule,
providers: UIRouterModule.forChild({ states: RouterUtil.setParentState(parentState, SOME_COMPONENT_STATES) }).providers
};
}
}
所以现在我可以在导入组件模块的同时配置其路由状态,如问题所示:
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule.importBelowState(SECTION_STATES[0].name)
]
})
export class AppSectionModule {}
我有一个由多个组件组成的应用程序,每个组件都定义了自己的路线状态子集。根据集成这些组件的应用程序,它们(app)提供父状态,某些组件状态应放置在父状态下。即
组件状态:
[{
name: 'component',
url: '/component',
component: ComponentRootComponent,
abstract: true,
default: '.list'
}, {
name: 'component.list',
url: '',
component: ComponentListComponent
},...]
这是一些应用部分模块:
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule,
UIRouterModule.forChild({
states: RouterUtil.setParentState(SECTION_STATES[0].name, SOME_COMPONENT_STATES)
})
]
})
export class AppSectionModule {}
setParentState()
函数只是遍历组件状态并在它们前面加上父状态名称前缀,因此它们低于特定的路由状态。
这一切都很棒,但与其为我的每个组件添加两个导入,我认为如果我为我的模块提供一个函数,允许我对每个组件有一个单一但可配置的导入会更好。
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule.importFor(SECTION_STATES[0].name)
]
})
export class AppSectionModule {}
importFor
因此应该 return ModuleWithProviders
类型,它是我的原始组件模块的包装器,它还应该定义组件路由并将其放置在特定的父路由下:
export class SomeComponentModule {
public static importFor(parentState: string): ModuleWithProviders {
return {
ngModule: SomeComponentModule,
providers: [
// what do I do here?
]
};
}
}
如何实现这样的功能?我不知道在这个功能中应该如何调用或提供UIRuterModule.forChild(...)
?这是我要解决的主要问题。
通过使用 "hidden" 模块,您可以完成此操作。
第一个模块有一个 forRoot() 或者在你的例子中有一个 importFor() 其中有一个指向隐藏模块的 ngModule。
这个模块是在调用 importFor 时导入的调用。 然后导入原始模块并将其导出以使其显示为隐藏。
我发现这是制作可重用模块的好方法,我可以简单地将这些模块放入我的项目中,所有东西都配置了 reducer、effects、routes 和所有 :)
@NgModule({
imports: [
SharedModule,
],
declarations: [
...SHARED_COMPONENTS,
],
exports: [
...SHARED_COMPONENTS,
]
})
export class SecurityModule {
// when the user imports SecurityModule.forRoot() in the app module what we really import is the RootSecurityModule
// but it will also create the IsAuthenticated guard
// it also imports all the feature stuff such as reducers, effects and routes
// if we then later on need to access shared components from the SecurityModule we can import the module without the forRoot()
static forRoot(): ModuleWithProviders {
return {
ngModule: RootSecurityModule,
providers: [
IsAuthenticatedGuard,
],
};
}
}
@NgModule({
imports: [
// import the above module so that we get all the shared declarations
SecurityModule,
// import the "include once" modules for security
StoreModule.forFeature('security', securityReducer),
EffectsModule.forFeature([
SecurityEffects
]),
SecurityRoutingModule,
],
// we need to export the SecurityModule otherwise SecurityModule.forRoot() will not mean the same thing as SecurityModule
exports: [
SecurityModule,
]
})
export class RootSecurityModule {}
检查 UIRouterModule 实际做了什么,这似乎按预期工作:
export class SomeComponentModule {
public static importBelowState(parentState: string): ModuleWithProviders {
return {
ngModule: SomeComponentModule,
providers: UIRouterModule.forChild({ states: RouterUtil.setParentState(parentState, SOME_COMPONENT_STATES) }).providers
};
}
}
所以现在我可以在导入组件模块的同时配置其路由状态,如问题所示:
@NgModule({
declarations: ...,
imports: [
UIRouterModule.forChild({ states: SECTION_STATES }),
SomeComponentModule.importBelowState(SECTION_STATES[0].name)
]
})
export class AppSectionModule {}