是否有类似于withLatestFrom的RxJS运算符但带有参数?

时间:2018-03-11 21:31:06

标签: angular rxjs ngrx

我的Angular 5应用程序基于NgRx,一个类似于Redux但基于RxJS的状态管理库。

我经常需要根据当前操作的有效负载从商店获取最新值。

在RxJS术语中,这意味着我的主流不断生成项目,而每个新项目我需要根据项目的值创建一个侧流,从此流中获取最新值,以及将它与主流相结合。

目前,我这样做:

@Effect()
public moveCursor$: Observable<Action> = this.actions$.pipe(
  ofType<TableAction.MoveCursor>(TableActionType.MOVE_CURSOR),
  switchMap(action => this.store$.select(selectTableById(action.payload.cursor.tableId)).pipe(
    first(),
    map(table => ({action, table}))
  )),
  map(({action, table}) => {
    ...
  })
)

我知道这可能不是最好的解决方案而且我正在寻找类似的东西(withLatestFrom运营商无法做到这一点):

@Effect()
public moveCursor$: Observable<Action> = this.actions$.pipe(
  ofType<TableAction.MoveCursor>(TableActionType.MOVE_CURSOR),
  withLatestFrom(action => this.store$.select(selectTableById(action.payload.cursor.tableId))),
  map(([action, table]) => {
    ...
  })
)

所以我的问题是:是否有任何类似于withLatestFrom的RxJS运算符可以将第一个流产生的值作为参数?

3 个答案:

答案 0 :(得分:3)

您可以使用mergeMapmap将操作与从商店中选择的表格结合使用:

@Effect()
public moveCursor$: Observable<Action> = this.actions$.pipe(
  ofType<TableAction.MoveCursor>(TableActionType.MOVE_CURSOR),
  mergeMap(action => this.store$
    .select(selectTableById(action.payload.cursor.tableId))
    .pipe(
      first(),
      map(table => [action, table])
    )
  ),
  map(([action, table]) => {
    ...
  })
)

您需要使用first - 或take(1) - 以确保从商店中选择的内部可观察量只发出一个值 - 表格是结合行动。

答案 1 :(得分:1)

我终于做到了...

doEffect$ = this.actions$.pipe(
    ofType<someAction>(losActionTypes.someAction),
    switchMap/mergeMap/concatMap(    // according to your logic
    action => of(action).pipe(
       withLatestFrom(this.store.pipe(select(leFancySelector)))
    )),
    tap(console.log)    // tap if you don't believe me

答案 2 :(得分:0)

不,从 rxjs 6 开始,我不相信有这样的内置运算符。我认为您当前的解决方案是最直接的方法,我也在使用该模式,重要的是要记住包含 first()take(1) 以避免响应选择器。