Ngrx:元 reducer 和捕获效果

标签 ngrx

我在我的 IStore 中添加了一个 transaction 概念。它直接代表提供一种将待处理操作保持待处理状态存储到我的 IStore 中的方法。当它们完成后,它们将被删除:

export interface IStore {
  user: IUser;
  txs: ITxRedux;
}

我所有的 reducer 都是这样的:

* reducer name: `'OPERATION'`
* success reducer name: `'OPERATION_SUCCESS'`
* failed reducer name: `'OPERATION_FAILED'`

其中一些 reducer (仅那些需要 http 请求的 reducer )是使用 @Effects 捕获的:

@Effect({ dispatch: true })
userLogin$: Observable<Action> = this._actions$
  .ofType('USER_LOGIN')
  .switchMap((action: Action) =>
  {
      ....
  });

目前,我的效果具有以下模式:

return make_http_call
  .map(_ => ({type: 'OPERATION_SUCCESS'}, payload: {...}))
  .catch(_ => ({type: 'OPERATION_FAILED'}, payload: {...}));

因此,我想通过在每次调用或完成效果时在我的 IStore.txs 中添加或删除 "transaction" 来找到一种方法。当我说“将交易添加到我的 IStore.txs 中”时,我的意思是调用“交易” reducer :

public static ADD_TX = `ADD_TX`;
private static addTx(txsRdx: ITxRedux, type, payload: ITx) {
    const tx = payload;

    return {
        ids: [ ...txsRdx.ids, tx.id ],
        entities: Object.assign({}, txsRdx.entities, {[tx.id]: tx}),
    };
}

public static REMOVE_TX = `REMOVE_TX`;
private static removeTx(txsRdx: ITxRedux, type, payload) {
    const tx: ITx = payload;
    var entitiesTmp = {...txsRdx.entities};

    delete entitiesTmp[tx.id];
    return {
        ids: txsRdx.ids.filter(id => tx.id != id),
        entities: entitiesTmp
    };
}

我听过一些关于元 reducer 的讨论,但我不太清楚他们是否能够实现我的目标。

有什么办法可以用优雅的方式得到它吗?

最佳答案

回复较晚,但您可能会发现 this post 有用。经典的例子(主要取自那篇文章)是通过日志元缩减器记录每个操作/状态更改:

export function logging(reducer) {

  return function loggingReducer(state, action) {
    console.group(action.type);

    // invoke following, "wrapped" reducer in the chain
    const nextState = reducer(state, action);

    console.log(`%c prev state`, `color: #9E9E9E`, state);
    console.log(`%c action`, `color: #03A9F4`, action);
    console.log(`%c next state`, `color: #4CAF50`, nextState);
    console.groupEnd();

    // return wrapped reducer output
    return nextState;
  };

}

在主应用程序模块中,您组合新的logging reducer 工厂与通常的combineReducers reducer 工厂:

const appReducer = compose(logging, combineReducers)(reducers);
//...
StoreModule.provideStore(appReducer),

只需注意设置 StoreModule 和全局应用程序缩减器,因为自该博客文章以来,该语法在最近的 ngrx 版本中已发生变化。

顺便说一句,如果您正在寻找实现元 reducer 来捕获和调用远程 API 调用的灵感,您可能需要查看一个等效的、已为 Redux 制作的中间件,如 redux-api-middleware 。 HTH

关于Ngrx:元 reducer 和捕获效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43911049/

相关文章:

javascript - 当使用 ngrx 和 Angular 6 从外部组件发出事件时,如何更新状态对象?

javascript - Angular2/Typescript/ngRx - 类型错误 : Cannot assign to read only property of object

angular - ngrx 突出显示网格中新添加的项目

angular - ngrx 商店选择器在从自定义库导入应用程序时失败

javascript - *ngIf 内的 viewChild 产生 undefined reference

angular - 尽管 DELETE 出错,实体仍从缓存中移除

angular - ngrx 效果中需要嵌套管道吗?

angular - karma 错误 : Cannot set property 'beforePreactivation' of undefined

angular - NGRX 选择器投影仪功能在 Jasmine 单元测试中返回未定义, Angular 10

angular - 带过滤器的 ngrx 选择器