以下是我的角度应用程序结构
app.module.ts
-- StoreModule.forRoot()
mainboard.module.ts
--StoreModule.forFeature('mainboard', reducer)
subFeature1.module.ts
subFeature2.module.ts
subFeature3.module.ts
dashboard1.module.ts
--StoreModule.forFeature('dashboard1', reducer)
subFeature1.module.ts
subFeature2.module.ts
subFeature3.module.ts
subFeature4.module.ts
subFeature5.module.ts
dashboard2.module.ts
--StoreModule.forFeature('dashboard2', reducer)
subFeature1.module.ts
subFeature2.module.ts
dashboard3.module.ts
--StoreModule.forFeature('dashboard3', reducer)
subFeature1.module.ts
subFeature2.module.ts
subFeature3.module.ts
subFeature4.module.ts
dashboard4.module.ts
--StoreModule.forFeature('dashboard4', reducer)
subFeature1.module.ts
subFeature2.module.ts
Run Code Online (Sandbox Code Playgroud)
所以要求是存储子功能。
像这样:
app.module.ts
-- StoreModule.forRoot()
mainboard.module.ts
--StoreModule.forFeature('mainboard', reducer)
subFeature1.module.ts
--StoreModule.forFeature('subFeature1', reducer)
subFeature2.module.ts
--StoreModule.forFeature('subFeature1', reducer)
subFeature3.module.ts
--StoreModule.forFeature('subFeature1', reducer)
...
Run Code Online (Sandbox Code Playgroud)
我如何才能为我的 NGRX/商店实现这样的层次结构?
app.module 是放置所有仪表板的地方。
dashboard-x.modules 是放置所有导航/项目的地方。
并在每个仪表板中包含子功能。
所以我的问题是关于如何使用 StoreModule.forFeature() 注册 subFeatures?
或者我是否需要为每个仪表板创建商店 (StoreModule.forRoot()),然后为每个子功能创建 StoreModule.forFeature()?(如果是这样,那么我如何才能在应用程序的 StoreModule.forRoot() 中注册它)
笔记
目前我正在将所有子功能注册为 forFeature.('subfeturename', reducer)
但问题在于,当我查看我的状态树(Redux devtools)时,它没有遵循上述存储树结构。由于所有子功能都注册为 forFeature(),因此所有子功能都显示为属性(即,它们没有按预期嵌套)。我想要的是我想让它们嵌套在我的状态树中。
所以如果我看看我的状态树,我可以看到嵌套状态像这样:
app
mainboard(open)
subFeature1
subFeature2
subFeature3
dashboard1(closed)
dashboard2(open)
subFeature1
subFeature2
dashboard3(closed)
dashboard4(closed)
//open and closed means expand and collapsed tree
Run Code Online (Sandbox Code Playgroud)
请记住,每个级别(应用程序 > 仪表板 1 > 子功能)都有不同的属性,需要由商店管理。因此,每个级别都需要一个商店。
有很多方法可以做到。根据我的经验,以下只是我的选择。
首先要注意 -
forFeature不会创建独立的商店上下文。它只是在调用之后连接新的减速器和效果forRoot,这些效果和减速器将从整个应用程序中获取所有操作,因此如果您发送updateMyLazyFeature(123)一个模块 - 所有通过其连接减速器的模块都forFeature将获取此操作和减少它,并且很容易发生数据冲突,当您认为只有您的模块会更新但实际上它也会影响应用程序的其他部分时。
当您想在独立功能上拆分您的商店时,您需要查看商店功能的使用方式。如果该功能在 1 个以上的模块中使用,则 angular 会在构建后将其放入共享文件中,并且与forRoot.
如果该功能在多个模块中使用 - 最好的地方是将其保留在forRoot. 如果您仅在特定模块中使用该功能,并且它是如此绑定以至于在其他任何地方使用它的机会为零 - 那么您可以将其作为单独的商店功能。
还有一种情况——如果你用 ngrx 存储实现一个库,那么你需要使用,
forFeature因为你不能forRoot从你的库中访问。
例如,我们有一个仪表板应用程序,用户必须登录。这意味着我们应该可以访问多个组件中的用户数据,在这种情况下,正确的位置是将功能放在forRoot.
除此之外,我们还有一个懒惰的注册模块,用户可以使用邀请链接来预填表单。因为预填充的数据不会在其他任何地方使用,并且注册模块也很少使用,我们可以像forFeature在注册模块中一样实现该功能。如果用户不打算在他的会话期间注册 - angular 根本不会加载模块和功能。
同样在通量模式中,保持数据平坦也很重要。Flux 和 ngrx 解决的主要问题是数据一致性,实现它的最简单方法是保持其平坦。
尽管模块像app -> mainboard -> subFeature1etc一样嵌套,但您仍然可以将它们添加到 store 的顶层,以便它们与其他 reducer 存储在同一级别。
store
users
mainboard
dashboard2
subFeature1
subFeature2
subFeature3
Run Code Online (Sandbox Code Playgroud)
没有必要让它像
store
users
mainboard
subFeature1
subFeature2
subFeature3
dashboard2
subFeature1
subFeature2
subFeature3
Run Code Online (Sandbox Code Playgroud)
It will bring complexity later when behavior of selectors, reducers and actions isn't so clear and predictable. 使用扁平结构,您可以轻松地将您的功能移动到另一个项目。
基于此信息,我会投票支持扁平结构并使用
store
users
mainboard
dashboard2
subFeature1
subFeature2
subFeature3
Run Code Online (Sandbox Code Playgroud)
代替
store
users
mainboard
subFeature1
subFeature2
subFeature3
dashboard2
subFeature1
subFeature2
subFeature3
Run Code Online (Sandbox Code Playgroud)
因为在第二种情况下,一个动作会同时更新dashboard1和,dashboard2并且需要一种技术,比如correlationId只影响一个特征,尽管它看起来像那样dashboard1并且dashboard2是不同的特征并且独立工作,这是一个错误的猜测。
| 归档时间: |
|
| 查看次数: |
3156 次 |
| 最近记录: |