Angular ngrx-store:如何在模块(主模块/功能模块)之间共享存储

Angular ngrx-store: How to share store among modules (main module / feature module)

我有两个 angular 模块:mainfeature:

主/根模块:

@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 模块都可以访问的全局/共享状态。)

  1. 可以吗?
  2. 这被认为是一种好的做法吗?

目前我不能那样做,因为主 AppState:

中没有 feature 状态
export interface AppState {
    router: RouterReducerState<RouterStateUrl>;
}

打字稿显示错误 this.store.select('feature') 因为没有 feature 主存储 AppState 键。

使用 selectorthis.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动作,虽然很丑