目前正在重构Angular应用程序以使用ngrx存储并有两个选项。这是我们应用程序的基本结构。我相信大多数Angular应用程序都以相同的方式构建:
AppComponent
|-- ContainerComponent
|-- ChildComponent1
| |-- GrandChildComponent
| |-- GrandGrandChildComponent
|-- ChildComponent2
ContainerComponent已注入Store<AppState>
。我试图解决的问题是GrandGrandChildComponent(比如DropDownMenu组件)必须根据应用程序的状态改变其行为(即在商店中发生的某些条件下禁用某些菜单项)并发出事件当点击菜单项时,ContainerComponent
(或任何其他组件,不是必要的祖先)可以对它做出反应。
有几种解决方法:
@Input
/ @Output
Store
注入任何需要了解状态的组件选项1是我在文档中阅读的最常见/推荐的模式。因此,只有ContainerComponent是胖的,所有的孩子都很瘦/愚蠢,并依赖于通过@Input
进入的状态。
但是从我看到的这种方法增加了很多样板,你必须添加不必要的属性,只是为了将状态传递给Grand Child组件。而且它也打破了关注点分离原则,因为任何中间组件都必须知道下面组件需要什么。如果它知道只有Grand 组件可用的细节,那么制作通用组件并不容易。
另一方面,方法2似乎解决了分离问题的问题,而且似乎也是更清洁的实施。但由于我使用redux
模式相对较新,我不确定这是否可行,也许我不知道我可能遇到的任何陷阱我在重构方面太深了。
我怀疑采取哪种方法。我应该注意哪些陷阱?
由于
答案 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