NgRx:存储模块创建多个实例

时间:2018-09-21 09:41:12

标签: angular typescript ngrx

使用ngRx,我的代码遇到问题。由于该项目规模巨大,而且更多的是设计问题,很抱歉,我没有提供一个最小的复制示例。

我有一个具有以下结构的项目:

AppModule
    PrimaryOutletModule
        SidenavComponent
        HeaderComponent

ExploitationComponentsModule [lazy loaded in AppRouting]
    MapComponent
    MaService

ServicesModule [imported in AppModule]
    HttpServicesModule
        ExploitationServicesModule
            ExploitationService

在此结构中,我将此模块添加到AppModule中:

@NgModule({
  imports: [
    StoreModule.forRoot(exploitationReducers),
  ]
})
export class ExploitationStoreModule { }

没有任何问题,我所有的代码都运行良好。但是,当我将其添加到PrimaryOutletModuleExploitationComponentsModuleExploitationServicesModule并将其从AppModule中删除时,它将停止工作。

我想将其从AppModule中删除,以避免创建可全局访问的商店(我想给它们提供有意义的范围)

我的第一个想法是记录selectdispatch事件,当我这样做时,我发现没有捕获到事件。将其添加到模块后:

constructor() { console.log('Store module instance created'); }

我看到了两个实例。在this SOF question之后,我意识到我必须使用forRoot的{​​{1}}方法。

但是由于我的StoreModule已经在使用它,所以我寻找解决方案并偶然发现this SOF question,说延迟加载的模块正在创建模块的新实例。

如果我正确理解,我将两次使用ExploitationStoreModule,从而导致我的forRoot有两个实例。

由于我想为模块提供正确的作用域,并且不让他们访问与其没有业务往来的商店(例如,ExploitationStoreModule不应该访问ExploitationModule),因此不想被迫将我所有的商店模块导入我的SupervisionStore中。

这带来了一个问题:一个人应该如何在应用程序中声明存储,以便它们不是全局的,而仅在各自的模块中提供?

1 个答案:

答案 0 :(得分:1)

您可以在功能模块中使用storeModule.forFeature。 但是,在加载模块后,状态将对整个应用程序可用。

一些额外的资源:

一个商店拥有应用程序的整个状态树,按照以下最佳实践,您应该只拥有一个商店(在某些极端情况下,性能可能会成为问题,您需要多个商店,我链接到redux文档其中有一个很好的解释)。

如果您使用Store<FooState>将商店导入到组件中,则打字稿仅了解FooState,但实际上您的商店拥有整个应用程序的状态,例如BarState

但是我个人不需要访问组件内部的商店,因为我使用的是选择器,而选择器实际上并不需要商店类型。例如this.store.select(selectEmployees)