У меня есть следующие эффекты NGRX, определенные в одном классе. Эффект loadPage$
работает отлично. Эффект loadSection$
работает, но по какой-то причине вызывает как действие SetPages, так и действие SetSections, хотя я только возвращаю действие SetSections. Есть идеи?
Эффекты
@Effect()
loadPages$: Observable<Action> = this.actions$.pipe(
ofType<GetPages>(GET_PAGES),
switchMap(() => {
return this.loanService
.getPages()
.pipe(
pluck('data', 'pages'),
tap((pages: Page[]) => pages[0].active = true),
map(pages => new SetPages(pages))
);
})
);
@Effect()
loadSections$: Observable<Action> = this.actions$.pipe(
ofType<SelectPage>(SELECT_PAGE),
switchMap((action: SelectPage) => {
console.log('loadPageSection$::action:', action);
return this.loanService
.getPageSections(action.payload)
.pipe(
pluck('data', 'pageSections'),
map(sections => new SetSections(sections))
);
})
);
Действия: Все действия определены в одном файле.
export const GET_PAGES = 'GET_PAGES';
export const SELECT_PAGE = 'SELECT_PAGE';
export const SET_PAGES = 'SET_PAGES';
export const SET_SECTIONS = 'SET_SECTIONS';
export class GetPages implements Action {
readonly type = GET_PAGES;
}
export class SelectPage implements Action {
readonly type = SELECT_PAGE;
constructor(public payload: string) {
}
}
export class SetPages implements Action {
readonly type = SET_PAGES;
constructor(public payload: Page[]) {
}
}
export class SetSections implements Action {
readonly type = SET_SECTIONS;
constructor(public payload: Section[]) {
}
}
export type LoanActions = GetPages | SelectPage | SetPages | SetSections;
Редукторы: Когда я помещаю console.log в SET_PAGES и SET_SECTIONS, я вижу, как оба экземпляра регистрируются во время эффекта loadSection $.
export function loanReducer(state: LoanState = initialState, action: LoanActions) {
switch (action.type) {
case SELECT_PAGE:
const pages = [ ...state.pages ];
deactivatePage(pages);
activatePage(action.payload, pages);
return { ...state, pages };
case SET_PAGES:
return { ...state, pages: [ ...action.payload ] };
case SET_SECTIONS:
return { ...state, sections: [ ...action.payload ] };
case GET_PAGES:
default:
return state;
}
}
РЕДАКТИРОВАТЬ, добавляя активные / деактивирующие функции
export const deactivatePage = (pages: Page[]) => chain(pages).find(page => page.active).set('active', false).value();
export const activatePage = (id: string, pages: Page[]) => chain(pages).find(obj => obj.id === id).set('active', true).value();
Действие вызывается нажатием кнопки внутри пользовательского компонента: this.store.dispatch(new SelectPage(page.id))