美文网首页
Angular技术点(NgRxStore)

Angular技术点(NgRxStore)

作者: 桃子是水果 | 来源:发表于2019-12-18 16:42 被阅读0次

    NgRx/Store

    @ngrx/store是基于RxJS的状态管理库。在NgRx中,状态是由一个包含action和reducer的函数的映射组成的。Reducer函数经由action的分发以及当前或初始的状态而被调用,最后由reducer返回一个不可变的状态。

    Action: Action是状态的改变。它描述了某个事件的发生,但是没有指定应用的状态如何改变。
    ActionReducerMapActionReducerMap注册了一系列的reducer,在应用中使用StoreModule对它进行配置。
    ActionReducer: 它被用于创建reducer,例如logger。
    MetaReducer: 在应用中使用StoreModule配置的MetaReducer构成了根的meta-reducer。
    StoreModule: StoreModule@ngrx/storeAPI中的一个模块,它被用来在应用模块中配置reducer。
    createFeatureSelector: 它为状态(state)创建一个feature selector。
    createSelector: 它创建一个selector用于生成一个指定的状态。
    Store: 它提供了Store.select()Store.dispatch()来与reducer协同工作。Store.select()用于选择一个selector,Store.dispatch()用于向reducer分发action的类型。

    一般使用ActionStore、以及一个自定义的State即可。


    安装

    npm安装即可,npm i @ngrx/store --save


    创建项目中需要管理的状态(xx.state.ts)

    State是一个单独的不可变的数据结构(可以理解为一个全局的共享数据集)。

    export interface XXState {
      isXX: boolean;  // 某某状态
      yyArr: Array<any>  // 某个数据数组
    }
    

    State通过Store.dispatch()一个action进行变更。


    创建项目中需要的Action类(xx.action.ts)

    NgRx的Action描述了状态的变化。对于每一个action,我们都需要创建一个继承自Action的类,同时定义其type和payload(payload是个可选参数)。

    export const XX = 'xx';
    export const YY = 'yy';
    
    // 每个action其实就定义了一个类型,action的类型
    export class ChangeXXAction implements Action {
      readonly type = XX;
      constructor() {}
    }
    export class ChangeYYAction implements Action {
      readonly type = YY;
      constructor(public payload: any) {}
    }
    
    // 导出对应的actions
    export type XXActions = ChangeXXAction |
                            ChangeYYAction;
    

    创建项目中需要的Reducer类(xx.reducer.ts)

    Reducer描述了任何一个action所对应的应用的state将怎样变化。

    // 引入action中定义的变量
    import * as xAction from './xx.action';
    
    // 默认的初始数据,在状态改变过程中新状态将会覆盖默认数据
    const initialState: XXState = {
      isXX: false,
      yyArr: ['DATA1','DATA2']
    };
    
    export function reducer(state = initialState, action:XXActions): XXState {
      switch(action.type) {
        case xAction.XX: {
          // ES2018的展开运算符合并对象,新的同key数据将会替换旧的
          // 否则就会添加新的key-value
          return {...initialState,isXX: true,yyArr: ['DATA3']};
        }
        case xAction.YY: {
          return {...initialState,isXX:payload.isXX,yyArr:payload.yyArr};
        }  
        default: {
          return state;
        }
      } 
    } 
    

    使用createSelector()创建选择器,用于绑定store数据

    首先需要创建一个索引文件(index.ts(名称任意))用来管理所有的State:

    export interface AppState {
      xx: XXState
      // 如果要管理多个状态,在这个接口中添加即可
    }
    
    // 引入需要的reducer
    import * as xxReducer from './xx.reducer';
    // 创建Action和Reducer间的映射关系(那个action走哪个reducer)
    export const reducers: ActionReducerMap<AppState> = {
      xx: xxReducer.reducer,
    };
    
    // @ngrx/store默认使用 combineReducers创建根meta-reducer。
    // 这里调用combineReducers即可
    const developmentReducer = combineReducers(reducers);
    // 如果在app.module.ts中不显示声明metaReducer的配置项目,那么这里可以省略
    export function metaReducer( state: any, action: any) {
      return developmentReducer(state, action);
    }
    
    
    // 创建选择器对应选择的状态类型
    export const getStateType = (state: AppState) => state.xx;
    // 创建要监视的状态(猜测)
    export const getXX = (state: XXState) => state.isXX;
    // 创建选择器(一个选择器只能监视一个State接口中的属性)
    export const getXXState = createSelector(
      getStateType,
      getXX
    );
    

    在app.module.ts中配置store:

     imports: [
       ...
       StoreModule.forRoot(reducers), // 上文中的reducers,需要引入
        ...
      ],
    

    在需要订阅数据的地方订阅数据(订阅后会自动更新):

    import * as stateRoot from './states/index';
    import { Subscription } from 'rxjs';
    
    private subScriptions: Array<Subscription> = [];
    ... 
    // 注入stroe
    constructor(private store: Store<stateRoot.AppState>) ...
    ...
    ...
    
    someFunc():void {
      // 订阅 
      // 这里返回的是Observable对象,需要进一步subscribe才能获取数据
      // 或者在前台使用"this.isXX$ | async"方式访问Observable对象
      // 前台直接访问的Observable对象变量一般后缀$ 
     subScriptions.push(this.store.select(stateRoot.getXXState).subscribe(value => this.isXX = value));
    }
    
    

    最终在销毁组件的时候取消订阅:

    ngOnDestroy() {
        this.subScriptions.forEach(subScription => {
          subScription.unsubscribe();
        });
      }
    

    相关文章

      网友评论

          本文标题:Angular技术点(NgRxStore)

          本文链接:https://www.haomeiwen.com/subject/tspunctx.html