Angular|Angular Ngrx Store Effect 和 Action 的交互流程

我们可以使用 Meta Reducer 即高阶 Reducer 的概念。
下面是一个典型的例子:Logger Meta Reducer.
该高阶 Reducer 在真实的归约器执行之前添加一些日志消息:

export function logger(reducer: ActionReducer): ActionReducer { return (state: AppState, action: any): AppState => { console.log('state', state); console.log('action', action); return reducer(state, action); }; }

logger 的输入是一个 reducer,返回一个新的与输入的 reducer 具有完全相同的签名的新 reducer,且在这个新的 reducer 里,会首先执行日志记录操作。这有点像 Java 里的面向切片编程技术(AOP).
所示的 logger() 元归约器函数接受 ActionReducer 类型的输入参数(即纯函数或归约器),并且还返回 ActionReducer 类型的函数。 返回的函数在返回包装的减速器之前将状态和操作变量记录到控制台。
回到 App Module 代码,定义一组 ModuleWithProviders 类来包装 StoreDevtoolsModule.instrument() 方法,以便稍后在 App Module 上导入它。
export const storeDevTools: ModuleWithProviders[] = !environment.production ? [StoreDevtoolsModule.instrument()] : [];

最后,将上述的 ModuleWithProviders 导入 App Module:
StoreModule.forRoot((reducers) as any, { metaReducers }),EffectsModule.forRoot(effects),storeDevTools,

实际上,StoreModule.forRoot() 方法还可以接收第二个参数,类型为 StoreConfig interface:
export declare type StoreConfig = { initialState?: InitialState; reducerFactory?: ActionReducerFactory; metaReducers?: MetaReducer[];

Store Side-Effect 【Angular|Angular Ngrx Store Effect 和 Action 的交互流程】将 Action 分派到 Store 的代码有时会导致一些副作用(Side Effect)。 例如,调度一个动作来将所有Hero 数据加载到应用程序中。 这样的操作会导致必须通过 Angular 服务与托管在服务器端(或云)上的 Web API 进行通信以返回英雄数据的 Side-Effect。 将操作分派到 Store 的代码的这种 Side-Effect,会导致与外部服务的通信。
Ngrx/effects 模块将副作用与容器组件隔离开来,并提供了一个简洁的解决方案来在支持 NgRX Store 的 Angular 应用程序中处理它们。 Ngrx/store 模块向 Store 发送一个操作,以传递从服务器检索到的任何结果或数据。
Angular|Angular Ngrx Store Effect 和 Action 的交互流程
文章图片

上图的交互场景概述如下:
  • ngrx/effects 模块监听分发到 Store 的动作。
  • 如果有一个 Effect 被钩住来监听一个分派的动作,这个 Effect 就会运行并执行。
  • 一旦 Effect 从服务器端接收到数据,它就会向 Store 发送一个新的 action,以便 reducer 启动并处理从 Effect 接收到的数据并相应地更新状态。

    推荐阅读