NGXS 延迟加载模块的状态与应用程序的其余部分不同
NGXS lazy-loaded module has different state than the rest of the app
我有一个 CoreModule
急切加载并包含主应用程序状态,还有一个 ContractHolder.module
使用 NgxsModule.forFeature([ContractHolderState])
声明要添加到主应用程序的新状态加载时。但是,延迟加载模块中的组件会看到 {}
的初始状态(因此未按照 ContractHolderState
中定义的方式进行初始化),稍后当 ContractHolderState
的 @Action
处理程序更新状态。
在应用程序的其余部分,我看到包含已初始化 ContractHolderState
的应用程序状态,但在 ContractHolderState
更新它时它不会更新!
所以简而言之,我的延迟加载模块根本看不到应用程序状态,而是看到一个由延迟状态更新的空对象 ContractHolderState
,而应用程序的其余部分看到为 ContractHolderState
定义的初始值,但它永远不会更新。
代码:
Core.module
,它定义了主应用程序状态并由 App.module
:
导入
const ngxsStates = [ConfigurationState, AuthenticationAuthorizationState];
@NgModule({
imports: [
NgxsStoragePluginModule.forRoot({
key: appStateNames.authorization,
}),
NgxsModule.forRoot(ngxsStates, { developmentMode: !environment.production }), // <--- NGXS states
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxPermissionsModule.forRoot(),
],
providers: [...],
exports: [...],
declarations: [...],
})
export class CoreModule {}
我有 ContractHolder.module
是延迟加载的:
@NgModule({
declarations: [MainViewComponent],
imports: [
CommonModule,
CoreModule, // <--- imports core module with the main state
RouterModule.forChild([{
path: '',
component: MainViewComponent,
}]),
NgxsModule.forFeature([ContractHolderState]) // <--- declares state
],
})
export class ContractHolderModule { }
这是 ContractHolderState
:
@State<ContractHolderStateModel>({
name: appStateNames.contractHolders,
defaults: {
contractHolders: [],
},
})
export class ContractHolderState {
@Selector()
static contractHolders(state: ContractHolderStateModel): IContractHolder[] {
return state.contractHolders;
}
}
这就是 app-routing.module
中的路由定义延迟加载 ContractHolder.module
的方式:
const routes: Routes = [
{
path: 'home-page',
component: PageComponent,
children: [
{
path: 'ch',
outlet: 'page',
loadChildren:
(): Promise<ContractHolderModule> => import('./contract-holder/contract-holder.module')
.then(m => m.ContractHolderModule) // <--- lazy-loaded ContractHolder.module
},
]
},
{
path: '**',
component: LoginComponent
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
现在合约持有者模块中使用的 main-view.component
通过 @Select(ContractHolderState.contractHolders) allCh$: Observable<IContractHolder[]>;
查看状态。我还尝试查看返回空对象的 this.store.snapshot()
。 ContractHolderState
更新状态后,它不再是一个空对象,但状态的其余部分(来自应用程序的其余部分)永远不会存在。
发生这种情况时,主应用程序会看到完整状态,但 ContractHolderState
始终具有其默认值 {contractHolders: []}
,并且永远不会更新。
问题在于导入 CoreModule
,它不止一次定义了主状态。我们有多个模块导入核心模块。我保留了 App 模块导入的核心模块,所有其他功能现在都在新的 SharedModule 中。
我有一个 CoreModule
急切加载并包含主应用程序状态,还有一个 ContractHolder.module
使用 NgxsModule.forFeature([ContractHolderState])
声明要添加到主应用程序的新状态加载时。但是,延迟加载模块中的组件会看到 {}
的初始状态(因此未按照 ContractHolderState
中定义的方式进行初始化),稍后当 ContractHolderState
的 @Action
处理程序更新状态。
在应用程序的其余部分,我看到包含已初始化 ContractHolderState
的应用程序状态,但在 ContractHolderState
更新它时它不会更新!
所以简而言之,我的延迟加载模块根本看不到应用程序状态,而是看到一个由延迟状态更新的空对象 ContractHolderState
,而应用程序的其余部分看到为 ContractHolderState
定义的初始值,但它永远不会更新。
代码:
Core.module
,它定义了主应用程序状态并由 App.module
:
const ngxsStates = [ConfigurationState, AuthenticationAuthorizationState];
@NgModule({
imports: [
NgxsStoragePluginModule.forRoot({
key: appStateNames.authorization,
}),
NgxsModule.forRoot(ngxsStates, { developmentMode: !environment.production }), // <--- NGXS states
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxPermissionsModule.forRoot(),
],
providers: [...],
exports: [...],
declarations: [...],
})
export class CoreModule {}
我有 ContractHolder.module
是延迟加载的:
@NgModule({
declarations: [MainViewComponent],
imports: [
CommonModule,
CoreModule, // <--- imports core module with the main state
RouterModule.forChild([{
path: '',
component: MainViewComponent,
}]),
NgxsModule.forFeature([ContractHolderState]) // <--- declares state
],
})
export class ContractHolderModule { }
这是 ContractHolderState
:
@State<ContractHolderStateModel>({
name: appStateNames.contractHolders,
defaults: {
contractHolders: [],
},
})
export class ContractHolderState {
@Selector()
static contractHolders(state: ContractHolderStateModel): IContractHolder[] {
return state.contractHolders;
}
}
这就是 app-routing.module
中的路由定义延迟加载 ContractHolder.module
的方式:
const routes: Routes = [
{
path: 'home-page',
component: PageComponent,
children: [
{
path: 'ch',
outlet: 'page',
loadChildren:
(): Promise<ContractHolderModule> => import('./contract-holder/contract-holder.module')
.then(m => m.ContractHolderModule) // <--- lazy-loaded ContractHolder.module
},
]
},
{
path: '**',
component: LoginComponent
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
现在合约持有者模块中使用的 main-view.component
通过 @Select(ContractHolderState.contractHolders) allCh$: Observable<IContractHolder[]>;
查看状态。我还尝试查看返回空对象的 this.store.snapshot()
。 ContractHolderState
更新状态后,它不再是一个空对象,但状态的其余部分(来自应用程序的其余部分)永远不会存在。
发生这种情况时,主应用程序会看到完整状态,但 ContractHolderState
始终具有其默认值 {contractHolders: []}
,并且永远不会更新。
问题在于导入 CoreModule
,它不止一次定义了主状态。我们有多个模块导入核心模块。我保留了 App 模块导入的核心模块,所有其他功能现在都在新的 SharedModule 中。