Эффект NGRX неправильно запускает несколько действий - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть следующие эффекты 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))

1 Ответ

1 голос
/ 19 февраля 2020

Я нашел виновника. Я использую сервер GraphQL и клиент Apollo в своем приложении Angular для запроса к серверу. Я использовал метод watchQuery клиента Apollo для получения данных.

Согласно документации watchQuery

Как вы знаете, метод Apollo.query возвращает Observable, который выдает результат, только один раз. Apollo.watchQuery также делает то же самое, за исключением того, что он может выдавать несколько результатов. (Сам запрос GraphQL по-прежнему отправляется только один раз, но наблюдаемая watchQuery также может обновляться, если, например, другой запрос вызывает обновление объекта в глобальном кэше клиента Apollo.)

При переключении Активный флаг в данных, он должен запускать обновление кэша watchQuery, вызывая другой эффект Ngrx. Преобразование моего watchQuery в простой query решило проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...