如何为我的角度应用程序注册ngrx子功能(StoreModule.forFeature())? [英] How to register ngrx sub features (StoreModule.forFeature()) for my angular app?

查看:130
本文介绍了如何为我的角度应用程序注册ngrx子功能(StoreModule.forFeature())?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的角度应用程序结构

Following is my angular app structure

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


所以要求是要存储子功能.

So the requirement is to have store for subfeatures.

赞:

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)


...


我如何实现我的NGRX/STORE的层次结构?

app.module放置了所有仪表板.

app.module is there all the dashboards are placed.

dashboard-x.modules是放置所有导航/项目的地方.

dashboard-x.modules are the places where all the navs/ items are placed.

,并且每个仪表板内都包含子功能.

and inside each dashboards sub features are included.

所以我的问题是关于如何使用StoreModule.forFeature()注册subFeatures?

So my question is about how to register subFeatures with StoreModule.forFeature()?

还是我需要为每个仪表盘(StoreModule.forRoot())创建商店,然后为每个subFeatures建立StoreModule.forFeature()?(如果是这样,那我怎么能在应用程序的StoreModule.forRoot()中注册它?

Or do I need to make stores for each dashboards (StoreModule.forRoot()) and then StoreModule.forFeature() for each subFeatures? (if so then how may I be able to register it inside the app's StoreModule.forRoot())

注意

当前,我正在将所有子功能注册为forFeature.("subfeturename",reduceer)

Currently I'm registering all of the subfeatures as forFeature.('subfeturename', reducer)

但是问题是当我查看状态树(Redux devtools)时,它没有遵循上面的存储树结构.由于所有子功能都已注册为forFeature(),因此所有子功能都显示为属性(即,它们未按预期嵌套).相反,我想要的是将它们嵌套在状态树中.

But the problem with this is that when I have a look at my state tree (Redux devtools) it is not following the above store tree structure. Since all the sub features are getting registered as forFeature() all of them are showing as properties (ie, they are not getting nested as expected). What I want instead is that I want to have them nested inside my state tree.

所以,如果我看一下状态树,我可以看到嵌套状态像这样:

So if I have a look at my state tree I can see nested state Like this:

app
    mainboard(open)
          subFeature1
          subFeature2
          subFeature3

    dashboard1(closed)

    dashboard2(open)
          subFeature1
          subFeature2

    dashboard3(closed)

    dashboard4(closed)

//open and closed means expand and collapsed tree

请记住,每个级别(应用程序> dashboard1>子功能)具有不同的属性,需要由商店进行管理.因此,每个级别都必须有一家商店.

推荐答案

有很多方法可以做到这一点.根据我的经验,下面只是我的选择.

There are a lot of ways to do it. Below will be only my option based on my experience.

要注意的第一件事- forFeature 不会创建独立的存储上下文.它只是在调用 forRoot 后的稍后阶段连接新的reducers和效果,这些效果和reducers将获得整个应用程序的所有操作,因此,如果您发送 updateMyLazyFeature(123)在一个模块中-通过 forFeature 连接其reducer的所有模块都将执行此操作并进行简化,当您认为只更新模块但很容易发生数据冲突.实际上,它也会影响应用程序的其他部分.

First thing to note - forFeature doesn't create an independent store context. It simply connects new reducers and effects on a later stage after a call of forRoot and these effects and reducers will be getting all actions from the whole application, so if you send updateMyLazyFeature(123) in one module - all modules that connected their reducers via forFeature will get this action and reduce it, and it's very easy to get data collisions, when you think that only your module will be updated but in reality it affects other parts of the application too.

要在独立功能上划分商店时,需要查看如何使用商店功能.如果功能在多个模块中使用,则angular在构建后会将其放入共享文件中,与 forRoot 相比,没有任何好处.

When you want to split your store on independent features you need to review how a store feature is used. If the feature is used in more than 1 module, angular will put it in the shared file after build and it doesn't have any benifit compare to forRoot.

如果该功能已在多个模块中使用-最好的地方是将其保留在 forRoot 中.如果您仅在特定模块中使用该功能,并且该功能是如此紧密以致在其他任何地方都无法使用它-那么您可以将其作为单独的商店功能使用.

if the feature is used in several modules - the best place would be to keep it in forRoot. If you use the feature only in a particular module and it's so tied that there's zero chance to use it anywhere else - then you can put it as a separate store feature.

另一种情况-如果您使用ngrx存储实现一个库,则需要使用 forFeature ,因为您无法从您的lib中访问 forRoot .

One more case - if you implement a library with ngrx store, then you need to use forFeature because you can't access forRoot from your lib.

例如,我们有一个仪表板应用程序,用户必须登录.这意味着我们应该可以访问多个组件中的用户数据,在这种情况下,正确的位置是将功能放置在 forRoot 中.

An example, we have a dashboard application and users have to login. It means that we should have access to user's data in several components, in this case the right place would be to put the feature in forRoot.

除此之外,我们还有一个懒惰的注册模块,用户可以使用邀请链接预填表格.因为预填充的数据不会在其他任何地方使用,并且很少使用注册模块,所以我们可以在注册模块中将功能实现为 forFeature .如果用户在会话期间不打算注册,那么angular根本就不会加载模块和功能.

Apart from that, we have a lazy registration module and a user can use an invitation link to prefill the form. Because the prefilled data won't be used anywhere else and the registration module is seldomly used too, we can implement the feature as forFeature in the registration module. If user isn't going to register during his session - angular won't be going to load the module and the feature at all.

在通量模式中,保持数据平坦也很重要.通量和ngrx解决的主要问题是数据一致性,而实现数据一致性的最简单方法是保持数据平坦.

Also in the flux pattern it's important to keep data flat. The main problem flux and ngrx solve is data consistency and the easiest way to achieve it is to keep it flat.

尽管模块嵌套,例如 app->主板->subFeature1 等,您仍然可以将它们添加到商店的顶层,以便将它们存储在与其他reducer相同的级别上.

Despite modules are nested like app -> mainboard -> subFeature1 etc, you still can add them to the top level of the store so they'll be stored on the same level as other reducers.

store
    users
    mainboard
    dashboard2
    subFeature1
    subFeature2
    subFeature3

没有必要像这样

store
    users
    mainboard
        subFeature1
        subFeature2
        subFeature3
    dashboard2
        subFeature1
        subFeature2
        subFeature3

后,它会带来复杂的时候选择器,减速器和行动的行为也不是那么清晰,可预测的.借助扁平结构,您可以轻松地将要素移至另一个项目.

It will bring complexity later when behavior of selectors, reducers and actions isn't so clear and predictable. With the flat structure you can move your feature to another project with ease.

基于此信息,我将投票支持平面结构并使用

Based on this info I would vote for the flat structure and would use

StoreModule.forFeature('logsControls', logsControls.reducer);

代替

StoreModule.forFeature('dashboard1', {
  logsControls: logsControls.reducer,
});
StoreModule.forFeature('dashboard2', {
  logsControls: logsControls.reducer,
});

因为在第二种情况下,动作将同时更新 dashboard1 dashboard2 ,并且需要诸如 correlationId 之类的技术仅影响一个功能,尽管看来 dashboard1 dashboard2 是不同的功能并且可以独立工作,这是一个错误的猜测.

Because in the second case an action will update both dashboard1 and dashboard2 and requires a technique like correlationId to affect only one feature, despite it looks like that dashboard1 and dashboard2 are different features and work independently, that's a wrong guess.

这篇关于如何为我的角度应用程序注册ngrx子功能(StoreModule.forFeature())?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆