angular 11 ngrx/store 使用理解

Fork Me On Github

angular 11 ngrx/store 使用理解

声明

ts
                             
export interface AuthSate {
    site: ISite;
    cart: any;
}

export const authFeatureKey = 'auth';

export interface AppState {
    [authFeatureKey]: AuthSate;
}

export const initialState: AuthSate = {
    site: null, // 初始化时,必须设置值,未设置(undefined)的将无法通知
    cart: null,
};

// 定义根据action 修改方法
const authReducer = createReducer(
    initialState,
    on(setCart, (state, {cart}) => ({...state, cart})),
    on(setSite, (state, {site}) => ({...state, site})),

    on(clearAuth, state => Object.assign({}, initialState)), // 返回初始化
);

export function reducer(state: State<AppState> | undefined, action: Action) {
    return authReducer(state, action);
}
1234567891011121314151617181920212223242526272829

Actions

定义action 用于修改Store中的数据

ts
  
export const setCart = createAction('[shop]SET_CART', props<{cart: ICart}>());
export const setSite = createAction('[shop]SET_SITE', props<{site: ISite}>());
12

相当于

ts
     
export const setCart = (cart: ICart) => ({
    type: '[shop]SET_CART',
    payload: {cart},
});
12345

Selectors

定义 selector 用于获取数据

ts
           
export const selectAuth = createFeatureSelector<AppState, AuthState>(authFeatureKey);

export const selectCart = createSelector(
    selectAuth,
    (state: AuthState) => state.cart
);

export const selectSite = createSelector(
    selectShop,
    (state: AuthState) => state.site
);
1234567891011

注册到程序中

注册根

app.module.ts

ts
   
StoreModule.forRoot({
    [authFeatureKey]: reducer,
}),
123

这是必须的如果没有全局数据,则

ts
 
StoreModule.forRoot({}),
1

也可以为某一个模块注册局部数据

ts
 
StoreModule.forFeature(authFeatureKey, reducer),
1

使用

  1. 设置
ts
           
export class AppComponent {
    constructor(
        private store: Store<AppState>,
    ) {

    }

    setSite() {
        this.store.dispatch(setSite({site: {}}));
    }
}
1234567891011
  1. 获取数据
ts
         
export class AppComponent {
    constructor(
        private store: Store<AppState>,
    ) {
        this.store.select(selectSite).subscribe(site => {
            // TODO
        });
    }
}
123456789

特别注意

获取数据是一直实时更新的,除非取消订阅了。

更新的频率是依赖 reducer 的,把 reducer 看作一个对象,对象上的某一个属性更新了,会触发其他的属性更新事件

例如:

ts
    
 this.store.select(selectSite).subscribe(site => {
    // 获取到的 site 的值
    this.store.dispatch(setCart({cart: {}})); // 这样会陷入死循环,更新了 cart 的值,也会触发 site 更新的事件
});
1234
点击查看全文
标签: angular
0 651 0
在 angular 项目中实现对页面的访问控制
按下回车键,焦点移动到下一个表单或提交表单
使用ng-template 显示tree结构数据
使用 ViewContainerRef.createComponent 替代 ComponentFactoryResolver
angular 12使用 KaTex 显示 AsciiMath 格式的公式