Angular Ngrx Store Effect 和 Action 的交互流程

举报
汪子熙 发表于 2022/12/14 09:51:00 2022/12/14
【摘要】 logger 的输入是一个 reducer,返回一个新的与输入的 reducer 具有完全相同的签名的新 reducer,且在这个新的 reducer 里,会首先执行日志记录操作。这有点像 Java 里的面向切片编程技术(AOP).

我们可以使用 Meta Reducer 即高阶 Reducer 的概念。

下面是一个典型的例子:Logger Meta Reducer.

该高阶 Reducer 在真实的归约器执行之前添加一些日志消息:

export function logger(reducer:
    ActionReducer<AppState>): ActionReducer<AppState> {
        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<T,
    V extends Action = Action> = {
        initialState?: InitialState<T>;
        reducerFactory?: ActionReducerFactory<T, V>;
        metaReducers?: MetaReducer<T, V>[];

Store Side-Effect

将 Action 分派到 Store 的代码有时会导致一些副作用(Side Effect)。 例如,调度一个动作来将所有Hero 数据加载到应用程序中。 这样的操作会导致必须通过 Angular 服务与托管在服务器端(或云)上的 Web API 进行通信以返回英雄数据的 Side-Effect。 将操作分派到 Store 的代码的这种 Side-Effect,会导致与外部服务的通信。

Ngrx/effects 模块将副作用与容器组件隔离开来,并提供了一个简洁的解决方案来在支持 NgRX Store 的 Angular 应用程序中处理它们。 Ngrx/store 模块向 Store 发送一个操作,以传递从服务器检索到的任何结果或数据。

上图的交互场景概述如下:

  • ngrx/effects 模块监听分发到 Store 的动作。
  • 如果有一个 Effect 被钩住来监听一个分派的动作,这个 Effect 就会运行并执行。
  • 一旦 Effect 从服务器端接收到数据,它就会向 Store 发送一个新的 action,以便 reducer 启动并处理从 Effect 接收到的数据并相应地更新状态。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。