一个基于ngrx的计数器例子

时间:2022-07-26
本文章向大家介绍一个基于ngrx的计数器例子,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

(1) 定义action

从@ngrx/store导入Action,新建一个Action的子类:

(2) 实现reducer,根据不同的action type,返回不同的store

store要存储的业务数据也定义在reducer里,当然也可以在单独的State.ts文件里实现:

reducer函数就是一个有限状态机,根据当前的状态和传入的action类型,返回新的状态:

有了action和reducer,应用程序还无法直接消费,需要通过Selector暴露。

import {createFeatureSelector, createSelector} from '@ngrx/store';

首先创建一个MemoizedSelector, 使用API createFeatureSelector:

export const getExampleState = createFeatureSelector<State>('example');

传入的类型参数为实际的业务数据类型,传入一个字符串作为selector的名称。

如果想通过state拿到具体的业务数据,调用createSelector,传入之前的FeatureSelector,以及一个map函数,该函数输入是一个state,输出是state包含的具体业务数据字段。

// 参数1:所有页面数据的一个抽象
// 参数2:如何通过state拿到包裹的业务数据
// 这算是Counter State的一个抽象,可以近似理解成页面数据State的一个子集
// 注意,这里的state.counter还不是具体的number,而是fromCounter.State,即: counter: fromCounter.State; 而fromCounter.State的定义:
/*
export interface State {
  counter: number;
}
*/
export const getCounterState = createSelector(getExampleState, (state: State) => state.counter);

还可以像搭积木一样,将createSelector返回的MemoizedSelector传给新的createSelector,像拼乐高一样构造出新的selector:

// 这个函数最后要传给store.select, 作为一个map function
/*
    输入1:某个具体的State,比如CounterState
    输入2:如何根据State拿到具体的值
    // select<K>(mapFn: (state: T) => K): Observable<K>;
    this.counter$ = store.select(fromExample.getCounterCounter);
*/
export const getCounterCounter = createSelector(getCounterState, fromCounter.getCounter);

(3) 应用程序的定义:

这个counter的赋值逻辑:

(1) 使用构造函数注入一个Store对象,类型参数为具体的业务数据结构

(2) 使用之前调用createSelector得到的selector,作为输入参数,传入到store对象的select方法里。

最后在页面里直接用$counter | async就可以显示当前的counter值了。

当然对counter的修改不能直接使用selector,实际上selector提供的只有读取方法;而是用store的dispatch方法,传入新的action来间接实现store里的数据修改动作。

最后一个步骤,在app module里从@ngrx/store导入StoreModule:

然后使用StoreModule.forFeature方法返回一个ModuleWithProviders:

要获取更多Jerry的原创文章,请关注公众号"汪子熙":