我在单个类中定义了以下NGRX效果。 loadPage$
效果很好。 loadSection$
效果有效,但是由于某种原因,即使我只返回SetSections操作,也会触发SetPages操作和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;
Reducers:当我将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))
我找到了罪魁祸首。我在Angular应用中使用GraphQL后端和Apollo客户端来查询服务器。我正在使用Apollo客户端的watchQuery
方法来获取数据。
根据watchQuery
文档
您知道,Apollo.query方法返回一个Observable,它仅发出一次结果。 Apollo.watchQuery也可以执行相同的操作,只是它可以发出多个结果。 (GraphQL查询本身仍然仅发送一次,但是,例如,如果另一个查询导致对象在Apollo Client的全局缓存中更新,则watchQuery observable也可以更新。)
切换数据上的活动标志时,它必须触发watchQuery
的缓存被删除,从而触发其他Ngrx效果。将我的watchQuery
转换为普通的query
解决了该问题。