ngrx / store 使用记录

项目中的组件通信,原以为使用 EventEmitter,再通过   subscribe  订阅传递消息

结果找了一圈都没发现相关代码,倒是一直有 this.store.patch  这种代码:

 

百度了一下,发现是一种状态管理工具(孤陋寡闻了):

        Angular中的状态管理大部分可以被service接管,那么在一些中大型的项目中,这样做的弊端就会显露出来,其中之一就是状态流混乱,不利于后期维护,后来便借鉴了 redux 的状态管理模式并配上 rxjs 流式编程的特点形成了 @ngrx/store 这么一个作用于 Angular 的状态管理工具。

        于是乎学了一下,不过百度出来的相关文章多数写的都比较笼统,只能做参考用,照搬代码总是会少些关键信息,最后还是结合项目,整理出了具体使用方法,这里做下记录,以备后需。基础的知识点这里就不描述了,百度一下有很多,直接记录代码(先图后码):

 

1、首先代码层次比较简单,用于测试,主要有三个文件,actions、reducer、state:

 

2、action 描述状态变化,对于每一个 action, 都要有一个继承自 Action 的类:

 

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

 

4、State是一个单独的不可变的数据结构(可以理解为一个全局的共享数据集);创建选择器,用于绑定store数据。

 

5、配置 reducer ,(这里的 info 应该是对应 AppState 里的 info 字段):

 

6、至此准备工作完成,引入 store,更新数据使用 dispatch:

 

7、获取数据使用 pipe:

 

 最后别忘了销毁:

 

界面效果:

 

 

代码:

actions.ts

import { Action } from "@ngrx/store";

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

export enum ActionTypes {
    ZOOM_IN = 'ZOOM_IN',
    ZOOM_OUT = 'ZOOM_OUT',
    ADD_OBJ = 'ADD_OBJ',
}

// 每个action其实就定义了一个类型,action的类型
export class ZoomInAction implements Action {
    readonly type = ActionTypes.ZOOM_IN;

    constructor() {
    }
}

export class ZoomOutAction implements Action {
    readonly type = ActionTypes.ZOOM_OUT;

    constructor() {
    }
}

export class AddObjAction implements Action {
    readonly type = ActionTypes.ADD_OBJ;

    constructor(public newObj: object) {
    }
}

// 导出对应的actions
export type ActionUnion =
    ZoomInAction |
    ZoomOutAction |
    AddObjAction;

 

reducer.ts

// 引入action中定义的变量
import { ActionTypes, ActionUnion } from "./actions";
import { InfoState } from "./state";

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

// 默认的初始数据,在状态改变过程中新状态将会覆盖默认数据
const defaultSettings: InfoState = {
    zoom: 1,
    object: {},
};

/**
 * 响应操作请求。(module 注册此 reducer)
 * @param state
 * @param action
 */
export function designerMimicsReducer(
    state: InfoState = defaultSettings,
    action: ActionUnion
) {
    switch (action.type) {
        case ActionTypes.ZOOM_IN:
            return {
                ...state,
                zoom: state.zoom + 0.2
            };
        case ActionTypes.ZOOM_OUT:
            return {
                ...state,
                zoom: state.zoom - 0.2
            };
        case ActionTypes.ADD_OBJ:
            return {
                ...state,
                object: action.newObj
            };
        default:
            return state;
    }
}

 

state.ts

import { createSelector } from "@ngrx/store";

export interface InfoState {
    zoom: number;
    object: object;
}

/* 要记录的变量列表 */
export interface AppState {
    info: InfoState;
}

export const selectInfo = (state: AppState) => state.info;

export const selectZoom = createSelector(
    selectInfo,
    (state: InfoState) => state && state.zoom
);

export const selectObject = createSelector(
    selectInfo,
    (state: InfoState) => state && state.object
)

 

posted @ 2022-06-16 16:01  名字不好起啊  阅读(126)  评论(0编辑  收藏  举报