Angular ngrx-store:如何在模块(主模块/功能模块)之间共享存储
Angular ngrx-store: How to share store among modules (main module / feature module)
我有两个 angular 模块:main 和 feature:
主/根模块:
@NgModule({
imports: [
StoreModule.forRoot({router: routerReducer}),
EffectsModule.forRoot([...]),
...
],
declarations: [],
...
})
export class AppModule {}
功能模块:
@NgModule({
imports: [
StoreModule.forFeature('feature', {someValue: someValueReducer}),
EffectsModule.forFeature([...]),
...
],
declarations: [],
...
})
export class FeatureModule {}
我需要访问主模块中的 'feature' 数据片段,以根据存储在 feature
模块中的数据有条件地显示/激活应用程序选项卡。
(换句话说,我需要所有模块 main 和任何 feature 模块都可以访问的全局/共享状态。)
- 可以吗?
- 这被认为是一种好的做法吗?
目前我不能那样做,因为主 AppState
:
中没有 feature
状态
export interface AppState {
router: RouterReducerState<RouterStateUrl>;
}
打字稿显示错误 this.store.select('feature')
因为没有 feature
主存储 AppState
键。
使用 selector
:this.store.select(selectFeatureValue)
我收到运行时错误:
export const selectFeatureModule = createFeatureSelector<FeatureState>('feature');
export const selectFeatureValue = createSelector(selectFeatureModule ,
(state: FeatureState) => state.someValue);
我在主 AppComponent 中遇到错误:
TypeError: Cannot read property 'someValue' of undefined
在我看来,这几乎违背了两者的目的:延迟加载模块和延迟加载商店。
您可能应该重新考虑您的设计。通常反之亦然,你需要在你的功能模块中使用主状态,这很好,因为你不能在没有主状态的情况下激活功能模块,反之亦然有点奇怪。
话虽这么说,延迟加载商店的主要思想是您的主商店中没有功能商店密钥,但它们会在应用程序生命周期内根据需要添加。所以,你可以做的是将你的 feature reducer 导入到你需要它的主模块组件中,然后直接从 feature reducer select。
但同样,这是一个人是否愿意做的问题。我不会。
我会重新考虑主模块中我需要的设计和东西,我会放入主模块 reducer/store。
我的解决方案:
- 提取了名为 core 的额外功能模块。我已经将其他模块所需的所有共享全局/状态重构为 core.
- 在 core 上使用共享状态的所有模块添加了依赖项(无循环依赖项)
- 使用来自 core 模块的 selectors typescript 没有问题表明 store
中没有这样的键
我认为,这是一个至少部分有效的问题。想象一下下面的结构:
appState
├── coreState
│
├── lazyModuleSate1
│ ├── subStateA
│ └── subStateB
│
└── lazyModuleSate2
├── subStateA
└── subStateB
coreState 可能包含有关用户、会话的公共信息...
惰性模块的 reducer 在处理操作时可能需要访问此类公共状态。
但是
核心模块的Reducer只看到coreState。
惰性模块的 Reducers(使用 ActionReducerMap 定义)只能看到它们自己的子状态。
对于大多数情况来说,它很好很干净,但有时,应该在 coreState 的条件下处理操作。
不会有问题的,coreState一直在store里
惰性模块中定义的 Metareducers 只能看到它们自己的 lazyModuleState。
处理子状态之间的互连仍然很有用,但它们对处理 coreState - lazyModuleSate 关系没有帮助。
只有在应用程序级别定义的全局 metareducers 才能看到 coreState。
这里可以进行handel动作,虽然很丑
我有两个 angular 模块:main 和 feature:
主/根模块:
@NgModule({
imports: [
StoreModule.forRoot({router: routerReducer}),
EffectsModule.forRoot([...]),
...
],
declarations: [],
...
})
export class AppModule {}
功能模块:
@NgModule({
imports: [
StoreModule.forFeature('feature', {someValue: someValueReducer}),
EffectsModule.forFeature([...]),
...
],
declarations: [],
...
})
export class FeatureModule {}
我需要访问主模块中的 'feature' 数据片段,以根据存储在 feature
模块中的数据有条件地显示/激活应用程序选项卡。
(换句话说,我需要所有模块 main 和任何 feature 模块都可以访问的全局/共享状态。)
- 可以吗?
- 这被认为是一种好的做法吗?
目前我不能那样做,因为主 AppState
:
feature
状态
export interface AppState {
router: RouterReducerState<RouterStateUrl>;
}
打字稿显示错误 this.store.select('feature')
因为没有 feature
主存储 AppState
键。
使用 selector
:this.store.select(selectFeatureValue)
我收到运行时错误:
export const selectFeatureModule = createFeatureSelector<FeatureState>('feature');
export const selectFeatureValue = createSelector(selectFeatureModule ,
(state: FeatureState) => state.someValue);
我在主 AppComponent 中遇到错误:
TypeError: Cannot read property 'someValue' of undefined
在我看来,这几乎违背了两者的目的:延迟加载模块和延迟加载商店。
您可能应该重新考虑您的设计。通常反之亦然,你需要在你的功能模块中使用主状态,这很好,因为你不能在没有主状态的情况下激活功能模块,反之亦然有点奇怪。
话虽这么说,延迟加载商店的主要思想是您的主商店中没有功能商店密钥,但它们会在应用程序生命周期内根据需要添加。所以,你可以做的是将你的 feature reducer 导入到你需要它的主模块组件中,然后直接从 feature reducer select。 但同样,这是一个人是否愿意做的问题。我不会。
我会重新考虑主模块中我需要的设计和东西,我会放入主模块 reducer/store。
我的解决方案:
- 提取了名为 core 的额外功能模块。我已经将其他模块所需的所有共享全局/状态重构为 core.
- 在 core 上使用共享状态的所有模块添加了依赖项(无循环依赖项)
- 使用来自 core 模块的 selectors typescript 没有问题表明 store 中没有这样的键
我认为,这是一个至少部分有效的问题。想象一下下面的结构:
appState
├── coreState
│
├── lazyModuleSate1
│ ├── subStateA
│ └── subStateB
│
└── lazyModuleSate2
├── subStateA
└── subStateB
coreState 可能包含有关用户、会话的公共信息...
惰性模块的 reducer 在处理操作时可能需要访问此类公共状态。
但是
核心模块的Reducer只看到coreState。
惰性模块的 Reducers(使用 ActionReducerMap 定义)只能看到它们自己的子状态。 对于大多数情况来说,它很好很干净,但有时,应该在 coreState 的条件下处理操作。 不会有问题的,coreState一直在store里
惰性模块中定义的 Metareducers 只能看到它们自己的 lazyModuleState。 处理子状态之间的互连仍然很有用,但它们对处理 coreState - lazyModuleSate 关系没有帮助。
只有在应用程序级别定义的全局 metareducers 才能看到 coreState。 这里可以进行handel动作,虽然很丑