typescript 如何调度空动作?

yiytaume  于 2022-12-14  发布在  TypeScript
关注(0)|答案(8)|浏览(114)

我使用的是ngrx/effects
如何分派空操作?
这就是我现在所做的:

@Effect() foo$ = this.actions$
    .ofType(Actions.FOO)
    .withLatestFrom(this.store, (action, state) => ({ action, state }))
    .map(({ action, state }) => {
      if (state.foo.isCool) {
        return { type: Actions.BAR };
      } else {
        return { type: 'NOT_EXIST' };
      }
    });

因为我必须返回一个操作,所以我使用return { type: 'NOT_EXIST' };
有没有更好的方法?

u3r8eeie

u3r8eeie1#

选择的答案不再适用于rxjs6。因此这里有另一种方法。
虽然我更喜欢过滤大多数情况下所描述的另一个答案,使用flatMap有时可以方便,特别是当你正在做复杂的事情,太复杂的过滤器函数:

import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { flatMap } from 'rxjs/operators';
import { EMPTY, of } from 'rxjs';

@Injectable()
export class SomeEffects {
  @Effect()
  someEffect$ = this._actions$.pipe(
    ofType(SomeActionTypes.Action),
    flatMap((action) => {
      if (action.payload.isNotFunny) {
        return of(new CryInMySleepAction());
      } else {
        return EMPTY;
      }
    }),
  );

  constructor(
    private _actions$: Actions,
  ) {
  }
}
xuo3flqw

xuo3flqw2#

我使用过类似的未知操作,但通常是在reducer的单元测试环境中。
如果您不愿意在效果中执行相同的操作,可以使用mergeMapObservable.of()Observable.empty()有条件地发出一个动作:

@Effect() foo$ = this.actions$
  .ofType(ChatActions.FOO)
  .withLatestFrom(this.store, (action, state) => ({ action, state }))
  .mergeMap(({ action, state }) => {
    if (state.foo.isCool) {
      return Observable.of({ type: Actions.BAR });
    } else {
      return Observable.empty();
    }
  });
hivapdat

hivapdat3#

从ngrx 8开始,如果你试图调度一个空的动作,你会得到一个运行时错误,所以我认为只要过滤掉它们,这样它们就不会被调度。

@Effect() foo$ = this.actions$.pipe(
    ofType(Actions.FOO),
    withLatestFrom(this.store, (action, state) => ({ action, state })),
    map(({ action, state }) => {
      if (state.foo.isCool) {
        return { type: Actions.BAR };
      }
    }),
    filter(action => !!action)
);
rdrgkggo

rdrgkggo4#

我会按照以下方式来做:

@Effect() foo$ = this.actions$
    .ofType(Actions.FOO)
    .withLatestFrom(this.store, (action, state) => ({ action, state }))
    .filter(({ action, state }) => state.foo.isCool)
    .map(({ action, state }) => {
      return { type: Actions.BAR };
    });
iugsix8n

iugsix8n5#

我寻找的解决方案涉及使用@Effect({ dispatch: false })

@Effect({ dispatch: false })
  logThisEffect$: Observable<void> = this.actions$
    .ofType(dataActions.LOG_THIS_EFFECT)
    .pipe(map(() => console.log('logThisEffect$ called')));
6jygbczu

6jygbczu6#

对于"rxjs": "~6.6.6",flatmap已被合并Map破坏,我们可以使用相同的行为

import { map, switchMap, catchError, mergeMap } from 'rxjs/operators';
import { of, EMPTY } from 'rxjs';

    addCategorie$ = createEffect(() =>
        this.actions$.pipe(
          ofType(ADD_CATEGORY),
          mergeMap((category) => this.categoryService.post(category.isCategoryOrVendor, category.model)
            .pipe(
              mergeMap(() => {
                this.backService.back();
                return EMPTY;
              }),
              catchError((error) => of(CATEGORY_ERROR(error)))
            )
          )
        )
      );
ntjbwcob

ntjbwcob7#

另一种情况(没有“of”、“Observables”等):

switchMap(([, projectId]) => {
  const result: Action[] = [];

  if (projectId === null) {
    return result;
  }

  result.push(GetAction({
    filter: {
      projectId,
    },
  }));

  // a lot of another cases

  return result;
}),
mklgxw1f

mklgxw1f8#

如果您不想分派动作,则只需将dispatch设置为false:

@Effect()
  foo$ = createEffect(() =>
    this.actions$.pipe(
      ofType(Actions.FOO),
      map(t => [])
    ),
    { dispatch: false }
  );

相关问题