angular - NGRX 效果错误地触发了多个动作
问题描述
我在单个类中定义了以下 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;
Reducers : 当我在 SET_PAGES 和 SET_SECTIONS 下放置一个 console.log 时,我看到在 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 客户端的全局缓存中更新,则 watchQuery observable 也可以更新。)
当在数据上切换活动标志时,它必须触发watchQuery
要更新的缓存,从而触发其他 Ngrx 效果。将我的转换watchQuery
为普通query
的解决了这个问题。
推荐阅读
- druid - Druid:缓存查找失败,因为在摄取期间“找到 Null 或 Empty Dimension”
- c# - 如何在 Linq Select 语句中将函数作为表达式传递?
- mysql - 如何通过产品 ID 获取不同的状态计数
- c - 如何计算比赛?
- django - django 自定义保存方法以更改默认数据库
- angular - 路由器历史中的 Ionic 4/Angular 循环
- python - 如何在 gRPC 客户端-服务器框架上强制进行多处理以进行网络爬取?
- algorithm - DBSCAN/OPTICS 算法中是否包含半径 epsilon?
- ruby-on-rails-4 - Rails 服务器在 GCP VM 实例上运行,但无法在浏览器上访问 rails 应用程序
- python-3.x - Selenium-Webdriver 允许在一个窗口中打开多个选项卡,但在加载配置文件时不允许?