NGRX效果错误地触发了多个动作

问题描述 投票:0回答:1

我在单个类中定义了以下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 typescript ngrx effects
1个回答
1
投票

我找到了罪魁祸首。我在Angular应用中使用GraphQL后端和Apollo客户端来查询服务器。我正在使用Apollo客户端的watchQuery方法来获取数据。

根据watchQuery文档

您知道,Apollo.query方法返回一个Observable,它仅发出一次结果。 Apollo.watchQuery也可以执行相同的操作,只是它可以发出多个结果。 (GraphQL查询本身仍然仅发送一次,但是,例如,如果另一个查询导致对象在Apollo Client的全局缓存中更新,则watchQuery observable也可以更新。)

切换数据上的活动标志时,它必须触发watchQuery的缓存被删除,从而触发其他Ngrx效果。将我的watchQuery转换为普通的query解决了该问题。

© www.soinside.com 2019 - 2024. All rights reserved.