相关推荐:《angular教程》
ngrx/store的灵感来源于redux,是一款集成rxjs的angular状态管理库,由angular的布道者rob wormald开发。它和redux的核心思想相同,但使用rxjs实现观察者模式。它遵循redux核心原则,但专门为angular而设计。
angular中的状态管理大部分可以被service接管,那么在一些中大型的项目中,这样做的弊端就会显露出来,其中之一就是状态流混乱,不利于后期维护,后来便借鉴了redux的状态管理模式并配上rxjs流式编程的特点形成了@ngrx/store这么一个作用于angular的状态管理工具.
storemodule:
storemodule是@ngrx/store api中的一个模块,它被用来在应用模块中配置reducer。
action:
action是状态的改变。它描述了某个事件的发生,但是没有指定应用的状态如何改变。
store:
它提供了store.select()和store.dispatch()来与reducer协同工作。store.select()用于选择一个selector,
store.dispatch(
{
type:‘add’,
payload:{name:‘111’}
}
)
用于向reducer分发action的类型。
@ngrx/store 状态管理的三个原则首先,@ngrx/store 同样遵守 redux 的三个基本原则:
单一数据源这个原则是整个单页应用的状态通过object tree(对象树)的形式存储在store 里面。
这个定义十分抽象其实就是把所有需要共享的数据通过javascript 对象的形式存储下来
state ={ application:'angular app', shoppinglist:['apple', 'pear']}
state is read-only(状态只能是只读形式)这个 ngrx/store 核心之一就是用户不能直接修改状态内容。 举个例子,如果我们需要保存了登录页面状态,状态信息需要记录登录用户的名字。 当登录名字改变,我们不能直接修改状态保存的用户名字
state={'username':'kat'},//用户重新登录别的账户为tomstate.username = 'tom' //在ngrx store 这个行为是绝对不允许的
changes are made with pure functions(只能通过调用函数来改变状态)由于不能直接需改状态,ngrx/store 同时引入了一个叫做reducer(聚合器)的概念。通过reducer 来修改状态。
function reducer(state = 'show_all', action) { switch (action.type) { case 'set_visibility_filter': return object.assign({}, state ,newobj); default: return state } }
ngrx/store使用实例1.安装@ngrx/storeyarn add @ngrx/store
2. 创建 state, action, reducerstate 状态:
app\store\state.ts
//下面是使用接口的情况, 更规范export interface tasklist { id: number; text: string; complete: boolean;}export const tasksall: tasklist[] = [ {id: 1, text: 'java article 1', complete: false}, {id: 2, text: 'java article 2', complete: false}]export interface appstate { count: number; todos: tasklist; // 如果要管理多个状态,在这个接口中添加即可}//这个是不用接口的情况// export interface appstate {// count: number;// todos: any;// // 如果要管理多个状态,在这个接口中添加即可// }
reducer
app\store\reducer.ts
// reducer.ts,一般需要将state,action,reducer进行文件拆分import { action } from '@ngrx/store';export const increment = 'increment';export const decrement = 'decrement';export const reset = 'reset';const initialstate = 0;// reducer定义了action被派发时state的具体改变方式export function counterreducer(state: number = initialstate, action: action) { switch (action.type) { case increment: return state + 1; case decrement: return state - 1; case reset: return 0; default: return state; }}
actions
如果需要把action 单独提取出来, 参考 后面的
5 如果想把action分离出来如何处理?
3. 注册store根模块:
app/app.module.ts
import { ngmodule } from '@angular/core';import { storemodule } from '@ngrx/store';// storemodule: storemodule是@ngrx/storeapi中的一个模块,// 它被用来在应用模块中配置reducer。import {counterreducer} from './store/reducer';@ngmodule({ imports: [ storemodule.forroot({ count: counterreducer }), // 注册store ],})export class appmodule {}
4. 使用store在组件或服务中注入store进行使用
以 app\module\article\article.component.ts 组件为例:
// 组件级别import { component } from '@angular/core';import { store, select } from '@ngrx/store';import { observable } from 'rxjs';import { increment, decrement, reset} from '../../store/reducer';interface appstate { count: number;}@component({ selector: 'app-article', templateurl: './article.component.html', styleurls: ['./article.component.css']})export class articlecomponent { count: observable<number>; constructor(private store: store<appstate>) { // 注入store this.count = store.pipe(select('count')); // 从app.module.ts中获取count状态流 } increment() { this.store.dispatch({ type: increment }); } decrement() { this.store.dispatch({ type: decrement }); } reset() { this.store.dispatch({ type: reset }); }}
模板页面:
app\module\article\article.component.html
<div class="state-count"> <button (click)="increment()">增加increment</button> <div>current count: {{ count | async }}</div> <button (click)="decrement()">减少decrement</button> <button (click)="reset()">reset counter</button></div>
这里使用了 管道符 async, 在子模块里直接使用快报错 , 如果在子模块要实现 数据的双向绑定也会报错,具体原因参照 课件说明的 问题: the pipe ‘async’ could not be found?
如何做到在模板页面中不使用管道 来渲染页面 ?
修改如下:
count: observable<number>;constructor(private store: store<appstate>) { // 注入store var stream = store.pipe(select('count')); // 从app.module.ts中获取count状态流 stream.subscribe((res)=>{ this.count = res; }) }
为了管理方便, 一般会把 type , state, actions,reducers 分开来管理
5 如果想把action分离出来如何处理?新建 \app\store\actions.ts 文件import { injectable } from '@angular/core';import { increment, decrement, reset } from './types';@injectable()export class counteraction{ // add=function(){} add(){ return { type: increment } }}// 就只这样导出是不行的// export function add1(){// return { type: increment }// }
在根模块 app.module.ts 注册import {counteraction} from './store/actions';... providers: [counteraction],
在组件中使用 – article.component.tsimport {counteraction} from '../../store/actions';export class articlecomponent implements oninit { constructor( private action: counteraction //注入counteraction ) { } increment() { // this.store.dispatch({ type: increment }); //把 actions分离出去 this.store.dispatch(this.action.add()); }}
更多编程相关知识,请访问:编程视频!!
以上就是浅谈angular中使用ngrx做状态管理的方法的详细内容。