NGRX: правильный способ создать «глобальное» действие, на которое реагируют несколько редукторов?

#javascript #angular #redux #ngrx

#javascript #angular #redux #ngrx

Вопрос:

Как правильно объявить «INIT_ACTION», на которое могут реагировать все редукторы в ActionReducerMap?

это пример того, как в моем коде мне нужны все 3 редуктора (изображения, теги, addedTags), чтобы реагировать на одно действие :

 import { ActionReducerMap, createFeatureSelector } from '@ngrx/store';

import * as fromRoot from '../../../store';

import * as fromImages from './image.reducer';
import * as fromTags from './tag.reducer';
import * as fromAddedTags from './added-tag.reducer';

export interface AnalysisState {
    images: fromImages.State;
    tags: fromTags.State;
    addedTags: fromTags.State;
}
export interface State extends fromRoot.State {
    analysis: AnalysisState;
}

export const reducers: ActionReducerMap<AnalysisState> = {
    images: fromImages.reducer,
    tags: fromTags.reducer,
    addedTags: fromAddedTags.reducer
};

export const getAnlysisState = createFeatureSelector<AnalysisState>('analysis');
  

это пример файла actions:

 import { Action } from '@ngrx/store';
import { Tag } from '../../models/tag.model';

export const enum AddedTagActionTypes {
    ADD_TAG = '[ANALYSIS] - Add Tag'
}

export class AddTag implements Action {
    readonly type = AddedTagActionTypes.ADD_TAG;
    constructor(public payload: Tag) {}
}

export type AddedTagActions = AddTag;
  

и это пример редуктора:

 import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';

import * as fromAddedTag from '../actions/added-tag.actions';
import { Tag } from '../../models/tag.model';

export interface State extends EntityState<Tag> {}
export const adapter: EntityAdapter<Tag> = createEntityAdapter<Tag>({
    selectId: tag => tag.id
});

export const initialState: State = adapter.getInitialState({});
export function reducer(state = initialState, action: fromAddedTag.AddedTagActions): State {
    switch (action.type) {
        case fromAddedTag.AddedTagActionTypes.ADD_TAG: {
            return adapter.addOne(action.payload, state);
        }

        default: {
            return state;
        }
    }
}
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();


export const getAllAddedTags = selectAll;
  

Ответ №1:

Действие проходит через все редукторы. Следовательно, если вы просто поместите оператор case для этого действия во все 3 редуктора, то он попадет во все 3 оператора case.

Если для определенного действия в редукторе нет инструкции case, то будет запущена инструкция case по умолчанию, которая просто возвращает исходное состояние, оставляя его неизмененным.

Это предполагает, что вы не ленивы в загрузке редукторов. Редуктор, конечно, будет запущен, только если он загружен.

Комментарии:

1. Но каков правильный способ объявить это глобальное действие, чтобы оно было типобезопасным во всех редукторах? редуктор (состояние = initialState, действие: fromAddedTag. Добавленные теги):

2. возможно, вы хотите использовать тип объединения … typescriptlang.org/docs/handbook /…