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

Kev*_*ing 50 state-management ngrx-store angular5 angular6

我最近在@ngrx/store学习Angular 6,而其中一个教程是使用@ngrx/store进行状态管理,但我不明白在场景后面使用@ngrx/store的好处.

例如,对于简单的登录和注册操作,以前通过使用该服务(让我们称之为AuthService),我们可以使用它来调用后端api,在AuthService中存储"userInfo"或"token",将用户重定向到"HOME"在我们需要通过使用DI获取userInfo的任何组件中注入AuthService,只需要一个文件AuthService处理所有内容.

现在,如果我们使用@ngrx/store,我们需要定义Action/State/Reducer/Effects/Selector,它可能需要写入4或5个文件来处理上述动作或事件,然后有时我们还需要调用backend api使用服务,这看起来要复杂多余......

在其他一些场景中,我甚至看到一些页面使用@ngrx/store来存储对象或对象列表,如网格数据.,是对某种内存存储使用情况的?

回到这个问题,为什么我们在Angular项目中使用@ngrx/store而不是服务注册存储? 我知道这是用于" 国家管理 "的用法,但究竟什么是"国家管理"?这是什么类似事务日志,我们什么时候需要它?我们为什么要在前端管理它?请随时在@ngrx /商店区分享您的建议或经验!

Jea*_*ier 26

我想你应该阅读关于Ngrx商店的那两篇帖子:

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

你会知道什么时候需要Flux.如果您不确定是否需要它,则不需要它.

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

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

第二篇文章是关于是什么让这些解决方案在Facebook的未读消息计数器问题出现在React世界中.

关于在服务中存储不可验证数据的解决方案.当您处理常量数据时,它可以正常工作.但是,当多个组件必须更新此数据时,您可能会遇到更改检测问题和不正确的更新问题,您可以使用以下方法解决:

  • 观察者模式与私人主体公共观察和下一个功能
  • Ngrx商店


dal*_*ows 18

我与 NgRx 合作已经三年多了。我在小型项目中使用了它,它很方便但不必要,并且我在非常适合的应用程序中使用了它。与此同时,我有机会参与一个没有使用它的项目,我必须说它会从中受益。

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

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

可以看到,不符合标准的CRUD操作网页的要求。以“Angular”方式进行操作给代码带来了如此复杂的程度,以至于变得非常难以维护,最糟糕的是,当我加入团队时,最后两名原始成员离开时没有任何定制的非 NgRx 解决方案的文档。

现在,自从使用 NgRx 重构应用程序一年后,我想我可以总结一下优点和缺点。

优点:

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

缺点:

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

作为结论,我想说,就我们而言,NgRx 是一个不错的选择。一开始要求很高,但后来一切都感觉自然且合乎逻辑。另外,当您检查要求时,您会发现这是一个特殊情况。我理解反对 NgRx 的声音,在某些情况下我会支持他们,但不会支持这个项目。我们可以使用“Angular”方式来完成它吗?当然,以前也是这么干的,但是搞得一塌糊涂。它仍然充满了样板代码,事情发生在不同的地方,没有明显的原因等等。

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


Sam*_*mmi 8

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

以下是我对 Ngrx 的抱怨:

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

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

  • 我同意这一点。我看到的 NgRx 的推理与为什么使用 RxJs 的推理非常相似。答案始终是“因为你可以使用 Observables 传输值”。真的吗?这并不是完全抛弃 Promise 的好理由——特别是考虑到内置语言支持 async/await,它使你的代码比你必须在 RxJ 中使用的所有令人费解的回调更容易阅读和理解。 (3认同)

Ale*_*ksa 6

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

  • 如果服务作为私有服务注入,它在 AOT 中不起作用。最佳实践是不要向组件的模板公开服务。相反,在组件中保留一个变量,并根据服务的变量获取/设置它。 (11认同)

Der*_*ite 5

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

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

有时,您需要为数据服务编写某种 api,如何输入和输出数据、查询等。许多规则,例如数据的不变性,以及定义明确的修改数据的单一路径。与服务器后端没有什么不同,但比 API 调用更快、响应更快。

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