Angular 6-为什么使用@ ngrx / store而不是服务注入

时间:2018-07-10 21:47:38

标签: angular5 angular6 ngrx-store state-management

我最近正在使用@ ngrx / store学习Angular 6,而本教程之一是使用@ ngrx / store进行状态管理,但是我不了解在后台使用@ ngrx / store的好处

例如,对于简单的登录和注册操作,以前通过使用服务(我们称其为AuthService),我们可能会使用它来调用后端api,存储“ userInfo”或“ token”在AuthService中,将用户重定向到“ HOME”页面,然后我们可以使用DI来将AuthService注入到需要获取userInfo的任何组件中,只需一个文件AuthService就可以处理所有事情

现在,如果我们使用@ ngrx / store,则需要定义 Action / State / Reducer / Effects / Selector ,可能需要写入4或5个文件来处理上述操作或事件,那么有时我们仍然需要使用服务来调用后端api,这似乎要复杂得多且冗余得多...

在其他情况下,我什至看到某些页面使用@ ngrx / store存储对象或对象列表(例如网格数据)。是用于某种内存的商店使用情况?

所以回到问题,我们为什么在Angular项目中在服务注册存储中使用@ ngrx / store?我知道这是用于“ 状态管理”的, 但是“状态管理”到底是什么?那是事务日志之类的东西,什么时候需要?我们为什么要在前端进行管理?请随时在@ ngrx / store区域分享您的建议或经验!

5 个答案:

答案 0 :(得分:17)

我认为您应该阅读有关Ngrx存储的这两篇文章:

如果第一个解释了Ngrx Store解决的主要问题,它还引用了React How-To的这一声明“似乎同样适用于原始的Flux,Redux,Ngrx Store或任何一般的商店解决方案”: / p>

  

您将知道何时需要助焊剂。如果不确定是否需要它,则不需要它。

对我来说,Ngrx商店解决了多个问题。例如,当您必须处理可观察对象时,以及某些可观察数据的责任在不同组件之间共享时。在这种情况下,存储操作和减速器可确保始终以“正确的方式”执行数据修改。

它还为http请求缓存提供了可靠的解决方案。您将能够存储请求及其响应,以便可以验证所发出的请求尚未存储响应。

第二篇文章是关于如何通过Facebook的未读消息计数器问题使此类解决方案出现在React世界中的。

关于在服务中存储不可观察数据的解决方案。当您处理常量数据时,它可以正常工作。但是,当几个组件必须更新此数据时,您可能会遇到变更检测问题和不正确的更新问题,可以通过以下方法解决:

  • 具有私有主题public可观察和下一个功能的观察者模式
  • Ngrx商店

答案 1 :(得分:6)

我几乎只阅读 Ngrx 和其他 Redux 之类的商店库的好处,而(在我看来)代价高昂的权衡似乎太容易被忽略了。这通常是我看到的唯一原因:“使用 Ngrx 的唯一原因是您的应用程序小而简单”。我想说,这只是不完整的推理,还不够好。

以下是我对 Ngrx 的抱怨:

  • 您将逻辑拆分为几个不同的文件,这使得代码难以阅读和理解。这违背了基本的代码内聚和局部性原则。必须跳到不同的地方来阅读操作是如何执行的,这很费脑力。
  • 使用 Ngrx,您必须编写更多代码,这会增加出现错误的机会。更多代码 -> 更多出现错误的地方。
  • Ngrx 商店可以成为所有东西的倾倒场,没有任何韵律或理由。它可以成为一个全球性的大杂烩,没有人可以对其进行连贯的概述。它可以不断成长,直到没有人再了解它。
  • 我在 Ngrx 应用中看到了很多不必要的深层对象克隆,这导致了真正的性能问题。
  • Ngrx 所做的大多数事情都可以使用基本的服务/外观模式来更简单地完成,该模式从其中的 rxjs 主题公开可观察对象。使用 ngrx 所需的 rxjs 知识已经使您有能力自己使用裸 rxjs。
  • 如果您有多个依赖于一些公共数据的组件,那么您仍然不需要 ngrx,因为基本的服务/外观模式已经明确地处理了这一点。
  • 如果多个服务依赖于它们之间的公共数据,那么您只需在这些服务之间创建一个公共服务。你仍然不需要ngrx。它一直是服务,就像它一直是组件一样。

对我来说,Ngrx 的底线看起来不太好。

答案 2 :(得分:2)

如果您的应用程序中的数据用于多个组件,则需要某种服务来共享数据。有很多方法可以做到这一点。

一个中等复杂的应用程序最终将看起来像一个前端后端结构,其中数据处理在服务中完成,并通过可观察对象将数据公开给组件。

在某一时刻,您将需要为数据服务编写某种api,如何获取和获取数据,查询等。许多规则,例如数据的不变性,以及定义良好的单个路径来修改数据。与服务器后端没什么不同,但是比api调用要快得多且响应迅速。

您的api最终看起来就像已经存在的许多状态管理库之一。它们的存在是为了解决难题。如果您的应用很简单,则可能不需要它们。

答案 3 :(得分:1)

我使用 NgRx 已经三年多了。我在小型项目中使用它,在那里它很方便但没有必要,我将它用于非常适合的应用程序中。与此同时,我有机会在没有使用它的项目上工作,我必须说它会从中受益。

在当前项目中,我负责设计新的 FE 应用程序的架构。实际上,我的任务是完全重构现有应用程序,该应用程序针对相同的要求使用非 NgRx 方式,并且存在错误、难以理解和维护,并且没有文档。我决定在那里使用 NgRx,我这样做是因为以下原因:

  • 应用程序对数据有多个参与者。服务器使用 SSE 推送独立于用户操作的状态更新。
  • 在应用程序启动时,我们加载大部分可用数据,然后使用 SSE 进行部分更新。
  • 根据可能来自 BE 和用户决定的多种条件启用/禁用各种 UI 元素。
  • 用户界面有多种变体。来自 BE 的事件可以更改当前可见的 UI 元素(对话框中的文本),甚至用户操作也可能会更改 UI 的外观和工作方式(如果用户单击某个按钮,可以将重复出现的对话框替换为零食)。
  • 必须保留多个 UI 元素的状态,以便在用户离开页面并返回相同的内容(或通过 SSE 更新)时可见。

如您所见,要求不符合标准的 CRUD 操作网页。以“Angular”的方式做这件事给代码带来了如此复杂的代码,以至于它变得非常难以维护,最糟糕的是当我加入团队时,最后两个原始成员离开时没有任何定制的非 NgRx 解决方案的文档。< /p>

自从重构应用程序使用 NgRx 一年后,我想我可以总结一下利弊。

优点

  • 该应用更有条理。状态表示易于阅读,按用途或数据来源分组,并且易于扩展。
  • 我们摆脱了许多失去用途的工厂、外观和抽象类。代码更简洁,组件更“笨”,来自其他地方的隐藏技巧更少。
  • 使用效果和选择器使复杂的状态计算变得简单,并且大多数组件现在只需注入存储并分派动作或选择所需的状态切片,同时实际一次处理多个动作即可实现完整功能。
  • 由于更新的应用要求,我们已经被迫重构商店,主要是 Ctrl + C、Ctrl + V 和一些重命名。
  • 多亏了 Redux Dev Tools,调试和优化变得更加容易(是的)
  • 这是最重要的 - 即使认为我们的状态本身是独一无二的我们使用的商店管理不是。它有支持,它有文档,并且找到一些难题的解决方案并非不可能互联网。
  • 小福利,NgRx 是另一种可以添加到简历中的技术:)

缺点

  • 我的同事是 NgRx 的新手,他们花了一些时间来适应和完全理解它。
  • 在某些情况下,我们引入了多次调度某些操作并且难以找到原因并修复的问题
  • 我们的效果是巨大的,这是真的。他们可能会变得凌乱,但这就是我们的拉取请求。如果这段代码不存在,它仍然会在其他地方结束:)
  • 最大的问题?操作由其字符串类型区分。复制一个动作,忘记将其重命名为繁荣,发生了与您预期不同的事情,您不知道为什么。

作为结论,我会说在我们的案例中,NgRx 是一个不错的选择。一开始要求很高,但后来一切都变得自然而合乎逻辑。此外,当您检查要求时,您会注意到这是一个特殊情况。我理解反对 NgRx 的声音,在某些情况下我会支持他们,但不会支持这个项目。我们可以使用“Angular”的方式来完成吗?当然,以前也是这样弄的,但是乱七八糟。它仍然充满了样板代码,在不同地方发生的没有明显原因的事情等等。

任何有机会比较这两个版本的人都会说 NgRx 版本更好。

答案 4 :(得分:0)

还有第三种选择,即在服务中使用数据并直接在html中使用服务,例如*ngFor="let item of userService.users"。因此,当在HTML中自动呈现添加或更新操作后在服务中更新userService.users时,就不需要任何可观察对象,事件或存储。