NGRX和子组件的状态管理

时间:2017-07-14 08:21:38

标签: angular redux ngrx ngrx-store

目前正在重构Angular应用程序以使用ngrx存储并有两个选项。这是我们应用程序的基本结构。我相信大多数Angular应用程序都以相同的方式构建:

AppComponent
|-- ContainerComponent
    |-- ChildComponent1
    |   |-- GrandChildComponent
    |       |-- GrandGrandChildComponent
    |-- ChildComponent2

ContainerComponent已注入Store<AppState>。我试图解决的问题是GrandGrandChildComponent(比如DropDownMenu组件)必须根据应用程序的状态改变其行为(即在商店中发生的某些条件下禁用某些菜单项)并发出事件当点击菜单项时,ContainerComponent(或任何其他组件,不是必要的祖先)可以对它做出反应。

有几种解决方法:

  1. 使用@Input / @Output
  2. 在组件之间进行通信
  3. Store注入任何需要了解状态的组件
  4. 选项1是我在文档中阅读的最常见/推荐的模式。因此,只有ContainerComponent是胖的,所有的孩子都很瘦/愚蠢,并依赖于通过@Input进入的状态。

    但是从我看到的这种方法增加了很多样板,你必须添加不必要的属性,只是为了将状态传递给Grand Child组件。而且它也打破了关注点分离原则,因为任何中间组件都必须知道下面组件需要什么。如果它知道只有Grand 组件可用的细节,那么制作通用组件并不容易。

    另一方面,方法2似乎解决了分离问题的问题,而且似乎也是更清洁的实施。但由于我使用redux模式相对较新,我不确定这是否可行,也许我不知道我可能遇到的任何陷阱我在重构方面太深了。

    IMO,这两种方法都为我提供了一种简单的方法来测试每个组件。

    我怀疑采取哪种方法。我应该注意哪些陷阱?

    由于

2 个答案:

答案 0 :(得分:2)

以下是Dan Abramov的redux创建者(ngrx的灵感来自于redux,所以很多相同的想法都适用于ngrx)必须在这个主题上说:

  

何时介绍容器?我建议您开始构建应用   首先是表示组件。最终你会意识到   你在中间组件上传递了太多道具。   当您注意到某些组件不使用他们收到的道具时   但只是将它们向前推进,你必须重新连接所有这些   中间组件只要孩子需要更多数据,它就是一个   介绍一些容器组件的好时机。这样你就可以得到   没有的数据和行为道具到叶子组件   在树的中间加载不相关的组件。这是   一个持续的重构过程,所以不要试图纠正它   第一次。当您尝试这种模式时,您将开发一个   直观的感觉,什么时候提取一些容器,只是   就像你知道什么时候提取功能一样。

来源: https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#7dc5

答案 1 :(得分:1)

这在很大程度上取决于每个组件的用例,无论它们有多少@Output和@Input。

我一直在使用你的第一种方法很长一段时间,如果你的Child / lower-order组件进行非常简单的交互(自上而下的数据,然后将一个事件发回给Parent)或者a哑组件(仅接受输入)。当然我的容器很大

但是,如果您的某个子组件最终有许多I / O并且还有许多其他具有相同的子组件,您可能希望将它们视为一个大孩子(来自Child的@Output()将留在Big-Child组件而不是传递给GrandParent组件)

自下而上拥有太多@Output()可能会给你带来头疼:)第二种方法可以让您的组件更容易阅读。

AppComponent |-- ContainerComponent |-- ChildComponent1 | |-- GrandChildComponent | |-- GrandGrandChildComponent |-- ChildComponentWithManyIO => Make them to be self-managed |--GrandChild with only Input |--GrandChild with many Inputs/Outputs ( Self-managed )

我对管理状态的想法来自这里:https://www.youtube.com/watch?v=eBLTz8QRg4Q