首页 > 解决方案 > NgRx - 在效果中选择 AppState

问题描述

我在我的 NgRx 应用程序中有一个效果,它需要将一个动作作为“副作用”分派,以及该效果应该分派的主要最终动作。但是这个“副作用动作”取决于我需要从 AppState 中选择的状态键。

恐怕我实现的方式不正确,因为总是在 AppState 键更改时调度副作用动作。我知道使用 NgRx 选择器会创建一个 Observables 流,但我不知道对此的正确实现是什么。

这是我的效果:

createNewTask$ = createEffect(() => this.actions$.pipe(
  ofType(fromAgendaActions.createNewTask),
  concatMap(action => this.agendaService.createNewTask(action.payload)
    .pipe(
      tap(() => {
        this.store.select(selectCurrentDate).subscribe(currentDate => {
          if(moment(action.payload.followUpDate).isBefore(moment().startOf('date'))) {
            this.store.dispatch(fromAgendaActions.getOverdueTasks());
          }
          if(moment(currentDate).startOf('date').isSame(moment(action.payload.followUpDate))) {
            this.store.dispatch(fromAgendaActions.getTasks({ payload: { date: moment(currentDate).format('DD-MM-YYYY') }}));
          }
            });
      }),
      map(() => fromAgendaActions.createNewTaskSuccess()),
      catchError(() => of({ type: fromAgendaActions.AgendaActionsTypes.CreateNewTaskFail, error: 'error' }))
    )
)));

标签: angularrxjsngrx

解决方案


没试过,但以下应该没问题:

createNewTask$ = createEffect(() =>
  this.actions$.pipe(
    ofType(fromAgendaActions.createNewTask),
    withLatestFrom(this.store.select(selectCurrentDate)),
    concatMap(([action, currentDate]) =>
      this.agendaService.createNewTask(action.payload).pipe(
        concatMap(() => {
          const actions = [];
          if (
            moment(action.payload.followUpDate).isBefore(
              moment().startOf('date')
            )
          ) {
            actions.push(fromAgendaActions.getOverdueTasks());
          }

          if (
            moment(currentDate)
              .startOf('date')
              .isSame(moment(action.payload.followUpDate))
          ) {
            actions.push(
              fromAgendaActions.getTasks({
                payload: { date: moment(currentDate).format('DD-MM-YYYY') },
              })
            );
          }

          actions.push(fromAgendaActions.createNewTaskSuccess());

          return from(actions).map(a => of(a));
        }),
        catchError(() =>
          of({
            type: fromAgendaActions.AgendaActionsTypes.CreateNewTaskFail,
            error: 'error',
          })
        )
      )
    )
  )
);

推荐阅读