首页 > 解决方案 > 如何在顶层定义减速器?

问题描述

我有两个减速器文件来处理我的模块中的两个状态区域......

export interface MyState {
  people: PeopleState;
  pets: PetState;
}

export const reducers: ActionReducerMap<MyState> = {
  people: peopleReducer,
  pets: petsReducer
};

这工作正常。但是,我有一些操作需要更新该州的两个领域。我想通过一个 reducer 文件来处理这个问题,该文件处理 MyState 级别的事情并可以更新人和宠物。我想将处理此问题的现有减速器保留在较低级别。

我看不到如何注册顶级减速器。按照现在的代码方式,添加到 ActionReducerMap 的任何 reducer 都必须作为属性添加到 MyState 中,而不是作为一个整体来处理 MyState。

有人有什么想法吗?

谢谢尼克

标签: ngrx

解决方案


我想这里唯一的解决方案是使用 metaReducer,查看这篇文章:https ://netbasal.com/implementing-a-meta-reducer-in-ngrx-store-4379d7e1020a

说明:metaReducer 是一种超越其他reducer 的reducer。它应该有它自己的行动,可以有它自己的效果。你可以这样使用它:

export function metaReducer( reducer ) {
  return function reduce( state: ParentState, action: MetaReducerAction ) {
     switch(action.type)
        case PARENT_ACTION:
          return {
            ...state,
            people: peopleReducer(state.people, new DoSthWithPeople()),
            pets: petsReducer(state.pets, new DoSthWithPets())
          }
        default:
          return reducer(state, action);
  }
}

在哪里:

interface ParentState {
   pets: PetsState,
   people: PeopleState
}

type MetaReducerAction = ParentAction <-- this has type PARENT_ACTION

所以工作流程是直截了当的。在您想要更新人和宠物状态的操作的地方,您需要调度 PARENT_ACTION,然后操作 DoSthWith... 将在两个状态切片上触发。如果您调度不同的操作(metaReducer 未处理的类型的操作,因此与 PARENT_ACTION 不同),那么它将允许其他减速器处理该操作(检查默认部分中的内容)。

最后一部分是配置,它应该是这样的:

StoreModule.forFeature(compose(metaReducer, combineReducers)(reducers))

减速器只是:

const reducers = {
   pets: petsReducer,
   people: peopleReducer
}

编辑:格式化


推荐阅读