浅析 Angular 数据状态管理框架:NgRx/Store
ngrx/store
是基于 RxJS 的状态管理库,其灵感来源于Redux
。在NgRx
中,状态是由一个包含action
和reducer
的函数的映射组成的。Reducer
函数经由action
的分发以及当前或初始的状态而被调用,最后由reducer
返回一个不可变的状态。
状态管理
在前端大型复杂Angular/AngularJS
项目的状态管理一直是个让人头疼的问题。在 AngularJS(1.x 版本)中,状态管理通常由服务,事件,$rootScope
混合处理。在 Angular 中(2+版本),组件通信让状态管理变得清晰一些,但还是有点复杂,根据数据流向不同会用到很多方法。
ngrx/store 中的基本原则
视图层通过dispatch
发起一个行为(action)、Reducer
接收action
,根据action.type
类型来判断执行、改变状态、返回一个新的状态给store
、由store
更新state
。
State
(状态) 是状态(state
)存储器Action
(行为) 描述状态的变化Reducer
(归约器/归约函数) 根据先前状态以及当前行为来计算出新的状态,里面的方法为纯函数状态用
State
的可观察对象,Action
的观察者——Store
来访问
Actions(行为)
Actions
是信息的载体,它发送数据到reducer
,然后reducer
更新store
。Actions
是store
能接受数据的唯一方式。
在ngrx/store
里,Action
的接口是这样的:
type
描述期待的状态变化类型。比如,添加待办 ADD_TODO
,增加 DECREMENT
等。payload
是发送到待更新store
中的数据。store
派发action
的代码类似如下:
Reducers(归约器)
Reducers
规定了行为对应的具体状态变化。是纯函数,通过接收前一个状态和派发行为返回新对象作为下一个状态的方式来改变状态,新对象通常用Object.assign
和扩展语法来实现。
开发时特别要注意函数的纯性。因为纯函数:
不会改变它作用域外的状态
输出只决定于输入
相同输入,总是得到相同输出
Store(存储)
store
中储存了应用中所有的不可变状态。ngrx/store 中的 store 是 RxJS 状态的可观察对象,以及行为的观察者。
可以利用 Store 来派发行为。也可以用 Store 的 select()方法获取可观察对象,然后订阅观察,在状态变化之后做出反应。
上面我们描述的是基本流程。在实际开发过程中,会涉及 API 请求、浏览器存储等异步操作,就需要 effects 和 services,effects 由 action 触发,进行一些列逻辑后发出一个或者多个需要添加到队列的 action,再由 reducers 处理。
使用 ngrx/store 框架开发应用,始终只维护一个状态,并减少对 API 的调用。
实战
实战主要介绍一个管理系统的登录模块。
创建 Form 表单
增加组件:
LoginComponent
,主要就是布局,代码为组件逻辑定义用户:
User Model
添加表单:在组件
LoginComponent
增加Form
表单
NGRX Store
按照上述的 4 个原则定义相应的Actions
reducers
定义状态在文件
auth.reducers.ts
中创建状态,并初始化
actions
定义行为
service
实现数据交互(服务器)
effects 侦听从 Store 调度的动作,执行某些逻辑,然后分派新动作
一般情况下只在这里调用 API
通过返回一个 action 给 reducer 进行操作来改变 store 的状态
effects 总是返回一个或多个 action(除非
@Effect with {dispatch: false})
)
版权声明: 本文为 InfoQ 作者【devpoint】的原创文章。
原文链接:【http://xie.infoq.cn/article/38ad1c47765c826166cd262ca】。文章转载请联系作者。
评论