首页 > 解决方案 > 在 ngrx 效果中使用 withLatesFrom 或 combineLatest 流组合

问题描述

我偶然发现了一个我无法解释的奇怪问题,这是我所指的效果代码:

import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { withLatestFrom, tap, map } from 'rxjs/operators';


@Injectable()
export class SomeEffects {
  constructor (
    private actions$: Actions,
    private smthStore1: Store<fromSmth1.State>,
    private smthStore2: Store<fromSmth2.State>,
    private smthStore3: Store<fromSmth3.State>,
    private smthStore4: Store<fromSmth4.State>,
    private smthStore5: Store<fromSmth5.State>,
  ) {}

  private common$ = combineLatest(
    this.smthStore1.select(fromSmth1.getSmth),
    this.smthStore2.select(fromSmth2.getSmth),
    this.smthStore3.select(fromSmth3.getSmth),
    this.smthStore4.select(fromSmth4.getSmth),
    this.smthStore5.select(fromSmth5.getSmth),
  ).pipe(
    map(([smth1, smth2, smth3, smth4, smth5]) => ({ smth1, smth2, smth3, smth4, smth5 }))
  );

  @Effect({ dispatch: false })
  public someEffect$ = this.actions$
    .pipe(
      ofType(actions.SOME_ACTION),
      withLatestFrom(this.common$),
      tap(([action, data]) => do something...),
    );
}

所以我有几个依赖于 common$ 流的效果。这是我构建的一个流,纯粹是为了不在每个效果中重复自己,而只是为相同的效果组合 actions$ 和 common$,但由于某种原因,这不起作用。应用程序只是停止加载而没有任何错误。

现在,如果我用LatestFrom 注释掉,应用程序将再次运行:

@Effect({ dispatch: false })
public someEffect$ = this.actions$
  .pipe(
    ofType(actions.SOME_ACTION),
//    withLatestFrom(this.common$),
    tap(([action, data]) => do something...),
  );

关于 rxjs 和 ngrx,我有什么遗漏吗?

角 5 RxJS 5

标签: angularrxjsngrxrxjs5ngrx-effects

解决方案


可能有很多原因,因为您只需要商店中的一些值试试这个

  private common$ = withLatestFrom(
    this.smthStore1.select(fromSmth1.getSmth),
    this.smthStore2.select(fromSmth2.getSmth),
    this.smthStore3.select(fromSmth3.getSmth),
    this.smthStore4.select(fromSmth4.getSmth),
    this.smthStore5.select(fromSmth5.getSmth)
  ).pipe(
    map(([smth1, smth2, smth3, smth4, smth5]) => ({ smth1, smth2, smth3, smth4, smth5 }))
  );

@Effect({ dispatch: false })
  public someEffect$ = this.actions$
    .pipe(
      ofType(actions.SOME_ACTION),
      concatMap(action => of(action).pipe(this.common$))
      tap(([action, {smth1, smth2, smth3, smth4, smth5}]) => do something...),
    );

另外,如果您想继续使用,则combineLatest需要将语法更改为

private common$ = combineLatest([
    this.smthStore1.select(fromSmth1.getSmth),
    this.smthStore2.select(fromSmth2.getSmth),
    this.smthStore3.select(fromSmth3.getSmth),
    this.smthStore4.select(fromSmth4.getSmth),
    this.smthStore5.select(fromSmth5.getSmth),
  ]).pipe(
    map(([smth1, smth2, smth3, smth4, smth5]) => ({ smth1, smth2, smth3, smth4, smth5 }))
  );

推荐阅读