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

Angular 6 - Why use @ngrx/store rather than service injection

我最近正在使用@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个文件来处理上面动作或事件,然后有时我们仍然需要使用服务调用后端 api,这似乎更加复杂和冗余...

在其他一些场景中,我什至看到一些页面使用@ngrx/store来存储对象或对象列表,如网格数据。是为了某种内存存储使用吗?

回到问题,为什么我们在 Angular 项目的服务注册存储上使用 @ngrx/store? 我知道这是为了“STATE MANAGEMENT”用法,但"STATE MANAGEMENT"到底是什么?那是像事务日志之类的东西吗?我们什么时候需要它?为什么我们要在前端管理它?欢迎在@ngrx/store区分享您的建议或经验!

我认为你应该阅读那两个 post关于 Ngrx 商店的文章:

如果第一个解释了 Ngrx Store 解决的主要问题,它还引用了 React How-To "that seems to apply equally to original Flux, Redux, Ngrx Store or any store solution in general":

You’ll know when you need Flux. If you aren’t sure if you need it, you don’t need it.

对我来说,Ngrx 商店解决了多个问题。例如,当您必须处理可观察对象时,以及当对某些可观察数据的责任在不同组件之间共享时。在这种情况下,store actions 和 reducer 确保将始终执行数据修改 "the right way".

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

第二个 post 是关于是什么让这种解决方案出现在 React 世界中的 Facebook 未读消息计数器问题。

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

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

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

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

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

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

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

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

以下是我对 Ngrx 的抱怨:

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

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

我使用 NgRx 已经三年多了。我在小型项目中使用它,它很方便但不是必需的,我在它非常适合的应用程序中使用它。与此同时,我有机会从事没有使用它的项目,我必须说它会从中获利。

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

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

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

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

优点:

  • 该应用程序更有条理。状态表示易于阅读, 按目的或数据来源分组,易于扩展。
  • 我们摆脱了许多失去的工厂、立面和抽象类 他们的目的。代码更轻量,组件'dumber',有 来自其他地方的隐藏技巧更少。
  • 复杂的状态计算使用效果变得简单 选择器和大多数组件现在可以完全正常运行 注入商店并派发动作或选择 同时处理多个操作时需要状态切片。
  • 由于更新的应用程序要求,我们被迫重构 已经存储,主要是 Ctrl + C、Ctrl + V 和一些重命名。
  • 感谢 Redux 开发工具,它更容易调试和优化(是的 真的)
  • 这是最重要的——甚至认为我们的州本身是独一无二的 我们正在使用的商店管理不是。它有支持,它有 文档并且找到一些解决方案并非不可能 网上的难题。
  • 小福利,NgRx 是您可以在简历中加入的另一项技术 :)

缺点:

  • 我的同事们是 NgRx 的新手,他们花了一些时间才熟悉 适应并充分理解它。
  • 在某些情况下,我们引入了一些操作被执行的问题 多次派遣,很难找到原因 并修复它
  • 我们的影响很大,这是真的。他们可能会变得凌乱,但就是这样 我们有请求请求。如果没有这段代码,它会 仍然在其他地方结束:)
  • 最大的问题?操作按其字符串类型区分。复制 一个动作,忘记重命名它和繁荣,不同的是 发生的事情超出你的预期,而你却不知道为什么。

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

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

NGRX有时会有很多文件和很多重复代码。目前正在为此进行修复。为 Angular 项目中非常常见的某些 NGRX 状态管理情况制作通用类型 类,例如寻呼机和从后端加载对象