从一个效果调度多个动作

Dispatch multiple action from one effect

嗨,我想在 "loadFullService$" 效果中发送我的新动作 "LoadConfig"。

怎么办?

    @Effect()
loadFullService$: Observable<Action> = this.actions$
    .ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
    .switchMap(action => {
        return this.apiService
            .loadFullService(action.payload)
            .map((service: Service) => new servicesActions.LoadFullServiceSuccess(service))
            .catch(error => of(new servicesActions.LoadFailureAction(error)));
    })
    ;

@Effect()
loadConfig$: Observable<Action> = this.actions$
    .ofType<servicesActions.LoadConfig>(servicesActions.LOAD_CONFIG)
    .switchMap(action => {
        console.log("action config", action);
        return this.apiService
            .loadConfig(action.id, action.name)
            .map((config: Configuration) => new servicesActions.LoadConfigSuccess(config))
            .catch(error => of(new servicesActions.LoadConfigFailure(error)));
    });

在构造函数中导入 Store 服务。

constructor(
  private store: Store<StoreType>,
)

然后在操作调用 this.store.dispatch(newAction) 中,在 ofType().

之后的任何位置使用 do 运算符(通常)

@Effect()
loadFullService$: Observable<Action> = this.actions$
  .ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
  .do(action => {
    this.store.dispatch(new servicesActions.LoadConfig(action.payload.id, action.payload.name))
  })
  .switchMap(action => {
    return this.apiService
      .loadFullService(action.payload)
      .map((service: Service) => new servicesActions.LoadFullServiceSuccess(service))
      .catch(error => of(new servicesActions.LoadFailureAction(error)));
  });

我过去喜欢的另一种通用方法是创建一个新的可观察对象:

@Effect()
loadFullService$: Observable<Action> = this.actions$
  .ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
  .switchMap(action => {
    return this.apiService
      .loadFullService(action.payload)
      .mergeMap((service: Service) => {
        return new Observable(observer => {
          const successAction = new servicesActions.LoadFullServiceSuccess(service));
          const newAction = new servicesActions.LoadConfig(action.id, successAction.name));
          observer.next(successAction);
          observer.next(newAction);
          observer.complete();
      });
    })
    .catch(error => of(new servicesActions.LoadFailureAction(error)));
});

缺点是它增加了更多的流失,有时遵循代码会变得有点困难。

最后,第三种方法:

@Effect()
loadFullService$: Observable<Action> = this.actions$
  .ofType<servicesActions.LoadFullService>(servicesActions.LOAD_FULL_SERVICE)
  .switchMap(action => {
    return this.apiService
      .loadFullService(action.payload)
      .mergeMap((service: Service) => {
        const successAction = new servicesActions.LoadFullServiceSuccess(service));
        const newAction = new servicesActions.LoadConfig(action.id, successAction.name));
        return Observable.from([successAction, newAction]);
      })
      .catch(error => of(new servicesActions.LoadFailureAction(error)));
  });

效果不是采用一个元素的函数。它们是流转换,您可以在这里使用 RxJS 的所有功能。例如,要获取您在标题中要求的内容:

@Effect()
loadConfig$: Observable<Action> = this.actions$
    .ofType<servicesActions.LoadConfig>(servicesActions.LOAD_CONFIG)
    .switchMap(action => Observable.of(
        new OtherAction(),
        new OtherAction2(),
    );

注意:这与 André 的回答中的第三个版本非常相似。