从NGRX中的另一个reducer内部访问reducer状态

时间:2018-11-18 06:25:41

标签: ngrx

我如何在NGRX中的另一个异化器中访问(读取)异化器状态? 这是与this非常相似的问题。 NGRX是否为此提供其他解决方案?

1 个答案:

答案 0 :(得分:0)

在考虑做类似的事情时,我偶然发现了这个问题。我需要从另一个化简器获取一些状态信息的副本,作为可以取消并恢复为“已记录”数据集的临时“编辑”数据集。

我最终扩展了我的UI缩减器(保留当前用户会话状态/编辑的缩减器),使其包含一个属性以保存来自数据缩减器(代表数据库中存储内容的缩减器)的数据副本)。这些数据是通过“开始”操作传递的。

这是我的UI操作的缩写副本:

import { Action } from "@ngrx/store";
import {
  ICableFeature
} from "../../shared/models";

export enum UIActionTypes {
  ...
  UI_EDIT_CUSTOM_TAGS_START = "[UI] Edit Custom Tags Start",
  UI_EDIT_CUSTOM_TAGS_UPDATE = "[UI] Edit Custom Tags Update",
  UI_EDIT_CUSTOM_TAGS_SAVE = "[UI] Edit Custom Tags Save",
  UI_EDIT_CUSTOM_TAGS_SUCCESSFUL = "[UI] Edit Custom Tags Successful",
  UI_EDIT_CUSTOM_TAGS_FAILED = "[UI] Edit Custom Tags Failed",
  UI_EDIT_CUSTOM_TAGS_CANCELED = "[UI] Edit Custom Tags Canceled"
}

...

export class EditCustomTagsStart implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_START;

  constructor(public payload: ICableFeature) {}
}

export class EditCustomTagsUpdate implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_UPDATE;

  constructor(public payload: ICableFeature) {}  // This payload has a copy of the data I needed from the other reducer.  Make sure it is a copy and not the same object!
}

export class EditCustomTagsSave implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_SAVE;

  constructor() {}
}

export class EditCustomTagsSuccessful implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_SUCCESSFUL;

  constructor() {}
}

export class EditCustomTagsFailed implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_FAILED;

  constructor(public payload: string) {}
}

export class EditCustomTagsCanceled implements Action {
  readonly type = UIActionTypes.UI_EDIT_CUSTOM_TAGS_CANCELED;

  constructor() {}
}

export type UIActions =
  ...
  | EditCustomTagsStart
  | EditCustomTagsUpdate
  | EditCustomTagsSuccessful
  | EditCustomTagsFailed
  | EditCustomTagsCanceled;

这是我的UI reducer的缩写副本:

import * as fromUI from "../actions/ui.actions";
import {
  IOrchestratorState,
  IOrchestratorStatusState,
  ICableFeature
} from "../../shared/models";
export const uiFeatureKey = "ui";

export interface State {
  showScroll: boolean;
  fillingGaps: boolean;
  fillGapStatus: IOrchestratorStatusState;
  currentFillGapState: IOrchestratorState;
  editingCustomTags: boolean;
  customTagEdits: ICableFeature;
}

export const initialState: State = {
  showScroll: true,
  fillingGaps: false,
  fillGapStatus: null,
  currentFillGapState: null,
  editingCustomTags: false,
  customTagEdits: null
};

export function reducer(state = initialState, action: fromUI.UIActions) {
  switch (action.type) {
    ...
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_START:
      return {
        ...state,
        editingCustomTags: true,
        customTagEdits: action.payload  // This is a copy of the data I needed from the other reducer
      };
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_UPDATE:
      return {
        ...state,
        customTagEdits: action.payload  // This is the updated information from user edits, not saved.  
                                        // I can also create a router guard that checks to makes sure the data in this 
                                        // property and the data in my Data store are the same before the page is deactivated
      };
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_SUCCESSFUL:
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_FAILED:
    case fromUI.UIActionTypes.UI_EDIT_CUSTOM_TAGS_CANCELED:
      return {
        ...state,
        editingCustomTags: false,
        customTagEdits: null
      };

    default:
      return state;
  }
}

如您所见,通过将数据作为操作中的有效负载从一个reducer传递到另一个reducer,我能够在我的reducer中维护纯函数。

我希望这会有所帮助!