Angular Redux-如何在大型应用程序中组织存储

Angular Redux-如何在大型应用程序中组织存储,angular,redux,ngrx,ngrx-store,state-management,Angular,Redux,Ngrx,Ngrx Store,State Management,我们正在使用Angular 7结合NGRX开发SPA。几个月前,我们已经迁移到NGRX,主要用于身份验证和会话数据。之后,我们也开始移动其他功能。我将描述这个问题以及我们头脑中的解决方案及其缺点。我将非常感谢您如何解决这个问题(如果您有)或如何解决问题的想法 使用Redux(NGRX)的动机 我们有需要在多个组件之间共享的数据。通过属性共享是不可能的,因为我们的组件是由角度路由器分隔的 通过重用加载的数据(如Auth/Session)减少请求数 性能-当组件使用ChangeDetectionSt

我们正在使用Angular 7结合NGRX开发SPA。几个月前,我们已经迁移到NGRX,主要用于身份验证和会话数据。之后,我们也开始移动其他功能。我将描述这个问题以及我们头脑中的解决方案及其缺点。我将非常感谢您如何解决这个问题(如果您有)或如何解决问题的想法

使用Redux(NGRX)的动机
  • 我们有需要在多个组件之间共享的数据。通过属性共享是不可能的,因为我们的组件是由角度路由器分隔的
  • 通过重用加载的数据(如Auth/Session)减少请求数
  • 性能-当组件使用
    ChangeDetectionStrategy.OnPush时,Angular的性能要快得多
  • 商业问题 在我们的应用程序中,我们有6个模块。每个模块至少有10个功能(页面)。他们之间只有很少的共同细节

    Redux商店的第一步 由于我们的主要问题是#1和#2(如上所述),我们从以下商店结构开始:

     {
      "authentication": {
        "isLoading": false,
        "error": {},
        "token": "auth-token"
      },
      "session": {
        "userDetailsIsLoading": false,
        "userDetailsData": {},
        "userDetailsError": {}
      }
    }
    
    到目前为止,一切顺利。它和所有Redux教程一样,都带有递增/递减/重置计数器

    迁移模块功能 这里的乐趣开始了,因为我们在应用程序中有很多功能(6个模块*10个功能=60+)。 第一个决定是使用每个特性的
    reducer
    ,而不是每个实体的
    reducer
    ,因为我们的页面具有相同类型的实体,但使用不同的过滤器获取。我们在服务器端过滤数据,因为数据量很大。 例:最近10篇文章,前10篇文章-都在同一页上

    因此,我们通过更多的减速机扩展了我们的门店:

    {
       "authentication": {},
       "session": {},
       "blogs-list": {},
       "blogs-add": {},
       "administration-users": {},
       "administration-add-user": {}
    }
    
    问题 动作型碰撞 是的,我们在使用format
    [Feature]Action Description
    时遇到了第一次类型冲突。 为了解决这个问题,我们决定添加一个名称空间
    [Module][Feature]Action Description

    大商店 这是最大的问题。整个商店变得非常大。当存储是干净的时,这不是问题,但是经过几次导航之后,存储包含了大量不需要的数据

    我们考虑的解决办法 延迟加载 Angular允许延迟加载所谓的
    NGRX功能
    。这意味着我们可以从共享数据(auth、session)开始,一旦打开一个模块,所有的简化程序都会添加到存储中。这个解决方案部分地解决了这个问题。如果您导航到所有模块,商店将再次变大

    切换到实体缩减器 这在理论上看起来很容易,但在实践中却很难。正如我提到的,我们有一种仪表板,其中显示相同的实体,但使用不同的过滤器和分页获取。在头脑中,我有一个想法,在这些情况下使用不同的减速器,例如:

    {
       "latest-entities": {
           "isLoading": bool,
           "data": {},
           "error": {},
       }, 
       "most-popular-entities": {
           "isLoading": bool,
           "data": {},
           "error": {},
       }
    }
    
    但我们还有另一个缺点。我们曾经将过滤器保存在功能存储中,一旦我们更改过滤器,效果就会触发数据重新加载。切换到这种架构,我们将数据重新加载的责任转移到
    容器上
    Container
    将负责向最新实体店
    和最受欢迎实体店
    分配操作。这个解决方案也会越来越大。这个问题不能通过重组减速机和仓库来完全解决

    不要将功能移动到Redux,而是将其保存在容器中 我们可以将功能逻辑保存在
    容器中
    ,并且只对跨模块数据(如会话、身份验证和通知)使用redux。这也是一种解决方案,但也有其缺点。我希望保持应用程序的一致性,而不是在容器和存储中都有业务逻辑

    重置存储 为了使存储更小,我们可以创建一个操作,将存储重置为初始状态,一旦不使用该功能,该状态将被调度。以下是一个例子:

      public ngOnDestroy(): void {
        this.store$.dispatch(new BlogStoreActions.DestroyAction());
      }
    

    我还不能发表评论,但你的问题让我好奇,所以我向twitter和一位ngrx维护者提出了这个问题

    以下是回应(来自韦斯·格里姆斯):

    如果存储变得太大,那么也许是时候重新考虑从客户端获取哪些数据了。您真的需要完整的数据模型吗?还是一个成对的向下视图模型就足够了?一次按位批量获取数据。获得50,然后根据需要再返回50(延迟加载)

    还可以利用angular中的延迟加载功能模块,将forFeature与NgRx一起使用,然后只加载所需的存储部分。但是再一次。如果关注的是大小,考虑最小化客户端数据,并将重负载卸载到后端。

    链接: