【发布时间】:2020-02-19 22:18:29
【问题描述】:
我在单个类中定义了以下 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))
【问题讨论】:
-
pages 数组包含像 { id:1, label:'Label', active:false } 这样的对象。
deactivatePage查找 active 为 true 的对象并将其设置为 false。activatePage在数组中查找 id 匹配的对象并将 active 属性设置为 true。我想既然我在那些函数中使用它之前复制了 pages 数组,那就没问题了。 -
如果这些是纯函数就好了。在每个
ofType之后,你可以放一个tap((act) => console.log(“effect”, act))并搜索动作的发送位置 -
通过注释掉
deactivatePage和activatePage方法进行测试。仍然奇怪的行为,但不同。单击按钮会触发loadSection$效果。注释掉函数后,SetPages 只在第一次点击时触发。然后每次后续点击只会触发 SetSections。 -
你能贴出调度动作和deactivatePage、activatePage代码的代码吗?
-
作为编辑添加到原始帖子
标签: angular typescript ngrx effects