使用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 { }
没有任何问题,我所有的代码都运行良好。但是,当我将其添加到PrimaryOutletModule
,ExploitationComponentsModule
和ExploitationServicesModule
并将其从AppModule
中删除时,它将停止工作。
我想将其从AppModule中删除,以避免创建可全局访问的商店(我想给它们提供有意义的范围)
我的第一个想法是记录select
和dispatch
事件,当我这样做时,我发现没有捕获到事件。将其添加到模块后:
constructor() { console.log('Store module instance created'); }
我看到了两个实例。在this SOF question之后,我意识到我必须使用forRoot
的{{1}}方法。
但是由于我的StoreModule
已经在使用它,所以我寻找解决方案并偶然发现this SOF question,说延迟加载的模块正在创建模块的新实例。
如果我正确理解,我将两次使用ExploitationStoreModule
,从而导致我的forRoot
有两个实例。
由于我想为模块提供正确的作用域,并且不让他们访问与其没有业务往来的商店(例如,ExploitationStoreModule
不应该访问ExploitationModule
),因此不想被迫将我所有的商店模块导入我的SupervisionStore
中。
这带来了一个问题:一个人应该如何在应用程序中声明存储,以便它们不是全局的,而仅在各自的模块中提供?
答案 0 :(得分:1)
您可以在功能模块中使用storeModule.forFeature
。
但是,在加载模块后,状态将对整个应用程序可用。
一些额外的资源:
一个商店拥有应用程序的整个状态树,按照以下最佳实践,您应该只拥有一个商店(在某些极端情况下,性能可能会成为问题,您需要多个商店,我链接到redux文档其中有一个很好的解释)。
如果您使用Store<FooState>
将商店导入到组件中,则打字稿仅了解FooState
,但实际上您的商店拥有整个应用程序的状态,例如BarState
。
但是我个人不需要访问组件内部的商店,因为我使用的是选择器,而选择器实际上并不需要商店类型。例如this.store.select(selectEmployees)
。