在角度2中使用商店(ngrx)有什么好处

时间:2016-05-31 08:08:20

标签: angular ngrx

我正在开发 angular 1.x.x 项目并考虑将代码升级为 angular 2

现在,在我的项目中,我有许多服务(工厂)处理数据,几乎将数据保存在 js 数组(缓存和存储)中,并使用下划线处理这些数据。

我在angular2中使用ngrx找到了很多例子。

使用商店比较使用数据服务处理数据有什么好处?

如果我有多种数据类型(库存,订单,客户......),我的应用是否需要多个商店?

如何构建(设计)我的应用以处理多种数据类型?

3 个答案:

答案 0 :(得分:69)

即使你的问题主要是基于意见的,我也可以给你一些想法,为什么ngrx是一个不错的选择。尽管人们说将所有应用程序状态都放在一个对象(单状态树)中并不是一个好主意。但是,在我看来,无论如何,你的州都会在那里。对于商店而言,它只是一次性的,并且突变是明确的,并且在整个过程中被追踪并且由组件在本地维护。此外,您还可以在应用程序中从商店中选择特定属性,因此您只能选择您关心的数据。如果你通过总是返回一个数组并使用Observables来在reducers中包含不变性,那么你可以使用ChangeDetectionStrategy OnPushOnPush为您带来不错的性能提升。让我们看一下从官方Angular docs中得到的下图:

enter image description here

如您所见,Angular App使用组件体系结构构建,从而生成组件树。组件上的OnPush表示只有输入属性发生更改时,更改检测才会生效。例如,Child BOnPushChild ADefault且你更改了Child A内的某些内容,Child B的更改检测器将不会被触发,因为没有输入属性发生了变化。但是,如果您更改Child B内的内容,Child A将会重新呈现,因为它具有默认的更改检测器。

关于性能和单一状态树的重要性。该商店的另一个优点是您可以实际推理您的代码和状态更改。因此,大多数Angular 1.x应用程序的实际情况是范围汤。这是来自Lukas Ruebbelke blog post的精美图片:

enter image description here

图片展示了它非常好。另一位来自Tero Parviainen的article讲述了他如何通过禁止ng-controller来改进他的Angular应用程序。这一切都涉及范围汤和管理不断变化的状态是一个困难。 redux动机说明以下see here

  

如果模型可以更新另一个模型,那么视图可以更新模型,   它会更新另一个模型,反过来,这可能会导致另一个模型   查看更新。在某些时候,你不再理解会发生什么   在你的应用程序中,你已经失去了对何时,为什么以及如何控制   它的国家。当系统不透明且不确定时,很难   重现错误或添加新功能。

通过使用ngrx / store,您实际上可以解决此问题,因为您将在应用中获得清晰的数据流。

由于ngrx受到redux的高度启发,我会说相同的main principles适用:

  • 单一事实来源
  • 州是只读的
  • 使用纯函数进行更改

所以,在我看来,最大的好处是你能够轻松跟踪用户交互和状态变化的原因,因为你发送动作并且总是导致一个点,而使用普通模型你必须找到所有参考并看看是什么改变什么和何时。

使用ngrx / store还可以使用devtools查看调试状态容器并还原更改。我想,时间旅行是redux的主要原因之一,如果你使用的是普通的旧模型,那就很难了。

@muetzerich提到的可测试性也是使用ngrx / store的好处。减少器是纯函数,并且这些函数易于测试,因为它们接受输入并简单地返回输出并且不依赖于函数外的属性并且没有副作用,例如, http调用等。

为了跳到底线,我想说不需要使用ngrx / store来做任何这些事情,但你会受到限制(上面提到的三个原则)的限制,它们提供了一个共同的模式,带来不错的好处。

问题:

如果我有多种数据类型(库存,订单,客户......),我的应用是否需要多个商店?

不,我不建议使用多个商店。

如何构建(设计)我的应用以处理多种数据类型?

Tero Parviainen的这个blog post可能会帮助您弄清楚如何设计您的商店。他解释了如何为示例应用程序设计应用程序状态树。

答案 1 :(得分:8)

关于使用您可以在documentation

找到的商店的好处的一个很好的解释

集中,不可变状态

所有相关的申请状态都存在于一个地方。这样可以更轻松地跟踪问题,因为错误发生时的状态快照可以提供重要的洞察力,并且可以轻松地重新创建问题。这也是一个众所周知的难题,例如在Store应用程序的上下文中撤消/重做,并且可以实现强大的工具。

<强>性能

由于状态集中在应用程序的顶部,因此数据更新可以依靠存储片段向下流过您的组件。 Angular 2用于优化这种数据流布置,并且在组件依赖于未发出新值的Observable的情况下可以禁用变化检测。在最佳商店解决方案中,这将是绝大多数组件。

<强>可测

所有状态更新都在reducers中处理,reducers是纯函数。纯函数非常易于测试,因为它只是输入,断言输出。这使得能够测试应用程序的最关键方面,而无需模拟,间谍或其他技巧,这些技巧可以使测试既复杂又容易出错。

多个商店?

IMO使用一个商店并将您的数据类型添加为商店中的属性。

答案 2 :(得分:6)

ngrx.store可以完成设计良好的组件/服务,并带来额外的好处。到目前为止,我很早就开始研究这是如何结合在一起的,这就是我发现的:

通过服务和组件获得难以维护的混乱非常容易。如果您有级联操作,复杂数据交互和对远程位置的调用,您最终会构建一个与ngrx中的action-reducer-store排列几乎相同的服务。小的纯粹的功能,可观察的等等ngrx已经拥有它,为什么不使用它并从它所代表的思想和模式中获益。

如果力量/鼓励在小的可测试功能中思考。为一个适度复杂的组件布置一个减速器或多个减速器可以强制执行一个可以消除这么多小时消耗陷阱的规则。没有什么可以吞下数小时,比如追踪源于回调队列的准多线程竞争条件。我确信这可以通过reducer实现,但它简化了对调用序列和调试状态的访问。

Angular2模式变得更容易。具有显示逻辑的模板,组件作为模板所需的所有零碎的聚集位置。服务变得更简单,因为它们只是进行远程调用或处理来自任何地方的数据的io。然后是用于维护和改变状态的动作和减速器,它触发所有其他部分响应新状态。我发现,使用组件/服务模式,任何一个都会变得越来越复杂,其副作用变得非常难以调试。我的服务最终存储状态并执行数据操作。

观测量。在rxjs.store中,一切都是可观察的,这是响应式应用程序的基础。将应用程序状态构建为可观察状态有时候有点神秘或不是非常简单,但是将其计算出来并做得很好会为此付出更大的回报。

我能看到的唯一不利因素是减速器变得非常快。似乎有很多情况下重复使用具有不同名称的相同代码。我的大脑尖叫着用参数&#39;起作用,但它并没有这样做。另一方面,这是应用程序的结构和状态以其所有细节表达的地方,因此必然会有很多。当出现问题时,不可避免地会出现问题,将问题作为问题来源的纯函数可以更容易地追踪和修复。