翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:43   844   0

翻译:使用 Redux 和 ngrx 创建更佳的 Angular 2

原文地址:http://onehungrymind.com/build-better-angular-2-application-redux-ngrx

Angular 状态管理的演进

如果应用使用单个的控制器管理所有的状态,Angular 中的状态管理将从单个有机的单元开始。如果是一个单页应用,一个控制器还有意义吗?我们从冰河世纪挣脱出来,开始将视图、控制器,甚至指令和路由拆分为更小的独立的单位。这是巨大的改进,但是对于复杂的应用来说,管理复杂的状态仍然是一个问题。对于我们来说,在控制器,服务,路由,指令和偶尔的模板中包含散步的状态是很常见的。可变的状态本身不是邪恶的,但是共享的可变状态则是灾难的入场券。

正如像 Angular 这样的现代 Web 框架永远地改变了我们以 jQuer 为中心的应用开发方式,React 从根本上改变了我们在使用现代 Web 框架时处理状态管理的方式。Redux 是这种改变的前沿和核心,因为它引入了一种优雅地,但是非常简单的方式来管理应用程序状态。值得一提的是,Redux 不仅是一个库,更重要的是它是一种设计模式,完全与框架无关,更巧的是可以与 Angular 完美合作。

整个文章的灵感来自 Egghead.io – Getting Started with Redux series by Dan Abramov. 除了创始人的说明没有更好的途径学习 Redux。它完全免费并且改变了我的编程方式。

redux 的美妙之处在于它可以使用简单的句子表达出来,总之,在我 “啊” 的时候就可以总结三个要点。

单个的状态树

redux 的基础前提是应用的整个状态可以表示为单个的被称为 store 的 JavaScript 对象,或者 application store, 它可以被特定的被称为 reducers 的函数操作。同样重要的是状态是不变的,应用中只有 reducers 可以改变它。如上图所示,store 是整个应用世界的中心.

状态的稳固和不变使得理解和预测应用的行为变得指数级的容易。

事件流向上

在 redux 中,用户的事件被捕获然后发布到 reducer 处理。在 Angular 1.x 中,经常见到的反模式用法就是带有大堆的管理本地逻辑的庞大的控制器。通过将处理逻辑转移到 reducer,组件的负担将会变得很轻微。在 angular 2 中,你经常看到除了捕获事件并通过 output 发射出去的哑的控制器。

如上图所示,你会看到两个事件流。一个事件从子组件发射到父组件,然后到达 reducer。第二个事件流发射到 service 来执行一个异步操作,然后结果再发射到 reducer 。所有的事件流最终都到达 reducer 。

状态流向下

事件流向上的时候,状态流从父组件流向子组件。Angular 2 通过定义 Input 是的从父组件向子组件传递状态变得很简单。这对 change detection 有着深刻的含义,我们将稍后介绍。

@ngrx/store

通过引入 Observableasync 管道,Angular 2 的状态管理变得非常简单。我的朋友 Rob Wormald 使用 RxJS 创建了被称为 @ngrx/store 的Redux 实现。 这给予我们组合了 redux 和 Observable 的强大力量,这是非常强大的技术栈。

示例应用

我们将创建一个简单的主-从页面的 REST 应用,它有一个列表,我们可以选择并编辑摸个项目,或者添加新项目。使用它来演示 @ngrx/store 进行异步操作,我们将使用 json-server 来提供 REST API , 使用 Angular 2 的 http 服务进行访问。如果你希望一个更简单的版本,可以获取 simple-data-flow 分支来跳过 HTTP 调用部分。

获取代码,让我们开始ect(stateItems).toEqual(result); });

我们可以清晰地表达期望两个 reducer 方法返回的结果,然后使用如下的断言。

it('UPDATE_ITEM', () => {
  let payload = { id: 1, name: 'Updated Item' },
      result = [ initialState[0], { id: 1, name: 'Updated Item' } ],
      stateItems = items(initialState, {type: 'UPDATE_ITEM', payload: payload});
expect(stateItems).toEqual(result);
});
it('DELETE_ITEM', () => {
  let payload = { id: 0 },
      result = [ initialState[1] ],
      stateItems = items(initialState, {type: 'DELETE_ITEM', payload: payload});
expect(stateItems).toEqual(result);
});

重温

我们学到很多概念,让我们快速重温我们头脑中的新知识。

  • redux 的主要核心是中心化状态,事件向上和状态向下。
  • @ngrs/store 实现使用 Observalbe 允许我们使用异步管道填充模板
  • 我们创建的 reducer 是一个简单的函数,接收一个关于 action 和 state 的对象,返回一个新对象
  • 我们的 reducer 函数必须是干净的,所以我们看到我们创建它而不用修改集合。
  • store 基本上是一个键值对集合,还可以处理事件,派发状态。
  • 我们使用 store.emit 来广播事件
  • 我们使用 store.select 来订阅数据
  • 在表单中创建本地数据复制品来忽略高层的修改。
  • 对于异步调用,我们通过 Observable 传递结果,在完成的时候使用 emit 事件来通知 reducer
  • reducer 易于测试,因为方法是纯粹的,约定是透明的。

通过 @ngrx/store 学习 redux 一直是我感觉到 “新程序员” 这种感觉最近的事情。多么有趣!举个例子,玩一玩,想想如何在日常项目中使用这种方法。如果你创建很棒的东西,在评论中分享它。

See Also:

ngrx in GitHub

ngrx store

ngRx example app in GitHub

Build a Better Angular 2 Application with Redux and ngrx

Redux DevTools Extension

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP