StoreModule.forRoot()和StoreModule.forFeature()

时间:2017-09-21 15:58:02

标签: angular ngrx-store ngrx-store-4.0

最近,ngrx商店改变了在角应用程序中注册商店变量的方式。

StoreModule.forRoot()和StoreModule.forFeature()之间有什么区别

我们是否需要注册两者才能使应用程序正常工作?

4 个答案:

答案 0 :(得分:12)

它与延迟加载的reducer一起使用。当你有(延迟加载)功能模块并且想要在该模块中注册reducer时,则使用forFeature。否则,在AppModule中使用forRoot

参考:https://github.com/ngrx/platform/blob/master/docs/store/api.md#injecting-reducers

答案 1 :(得分:7)

始终导入forRoot()调用 我认为这可能非常明显,但只是为了记录,您需要确保已经在主应用程序中导入了根存储和效果模块。

imports: [
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    ...

如果您有适用于此级别的缩减器或效果,则应在此处添加它们,但即使您在应用程序的根级别没有任何缩减器或效果,也需要进行这两个调用。否则,forFeature()调用将无法访问根存储或效果位置以添加该功能的reducers和效果。

答案 2 :(得分:3)

首先,为了轻松处理 Angular 模块,您必须了解一些基本术语,这些术语将有助于您将来解决类似的问题。

Angular 应用程序(基本上)由一个名为“AppModule”的模块组成,该模块通常称为 Root Module:这是应用程序的主模块,在 main.ts 文件,实际上是应用程序入口点。当您将一些外部模块导入 AppModule 的 imports 数组时,您通常会调用静态方法 forRoot 来为该模块提供初始配置:这是 StoreModule 的情况forRoot 方法,用于设置商店的初始配置。

您可以开发您的应用程序,找到一些“关注区域”来解决您的问题的特定部分。当您将组件、指令、服务和其他 Angular 元素合并到一个模块中时,该模块将成为一个功能模块,因为正如命名约定所暗示的那样,它为您的应用程序提供了一项功能。无论您如何加载模块(Eagerly 或 Lazily),它始终是一个功能模块。

现在,也许您已经自己回答了您的问题:

  1. forRoot 方法在 AppModule 中调用,通常,在应用程序中调用一次以初始化 Store 并提供初始的 reducers/actions/state 配置.如果您使用 EffectsModule,您也会在此模块上调用 forRoot 方法:

    @ngModule({ 进口:[ StoreModule.forRoot(), EffectsModule.forRoot() ] }) 类 AppModule {}

  2. forFeature 方法在任何需要它自己的状态管理部分的功能模块中调用:例如,一个 UserModule 将定义它自己的状态部分,描述所需的动作,减速器等。如果您使用 EffectsModule,请记住也针对它调用 forFeature 方法。正如您自己所理解的,forFeature(作为更通用的 Angular 的 forChild 方法)可以为应用程序中的同一个导入模块多次调用:

    AppModule -> StoreModule.forRoot(...) UsersModule -> StoreModule.forFeature(...) 其他模块 -> StoreModule.forFeature(...)

最后,请记住 forRoot 和 forFeature 签名彼此略有不同:实际上,后者具有描述功能名称的第一个参数。其他参数,如果我没记错的话,与 forRoot 方法相同。如果您尝试使用以下命令为带有 @ngrx/schematics 包的功能模块生成样板:

ng generate feature user/User -m modules/users/users.module.ts --group

您会发现功能名称只是给定命令中用户单词的小写版本:user。 >

答案 3 :(得分:2)

在角度项目中,您可以使用Feature modules将应用程序划分为重点区域,因此很自然地可以使用StoreModule.forFeature()将功能存储在其自己的模块中,然后将该模块导入到主应用模块。您应该记住,即使您已对整个应用程序进行了模块化,主模块也应具有StoreModule.forRoot(),但您应将StoreModule.forRoot({})与一个空对象一起使用,以便在导入功能模块时它将其状态附加到您的状态。

注意:延迟加载的模块是一种功能模块,因此您可以使用StoreModule.forFeature()来设置应用程序那部分的状态。