ngrx异步元化简

时间:2019-03-24 00:38:20

标签: angular ngrx

我有一个ngrx meta-reducer,它可以像这样调整动作的有效负载:

export function doSomething(reducer) {
  return (state, action) => {
    action.payload = 'fred'
    return reducer(state, action)
  }
}

export const metaReducers: MetaReducer<State>[] = [doSomething]

这很好。但是,我希望有效负载由异步HTTP请求的响应确定。像这样:

export function doSomething(reducer) {
  return (state, action) => {
    // ASSUME THE HTTP SERVICE IS AVAILABLE AS MAKING THE HTTP SERVICE AVAILABLE IS NOT A PROBLEM (trying to keep the code simple for illustration)
    this.http.get('/some/data').subscribe((res) => {
      action.payload = res.data
      return reducer(state, action)
    })
  }
}

但这不起作用。有人知道如何实现这一目标吗?

1 个答案:

答案 0 :(得分:0)

对此解决方案不满意,但这是一种解决方法。如果有人知道如何编写异步meta reducer,我会更开心:)

对于任何以“ Requested”结尾的类型触发的动作,此代码都会发出HTTP请求,然后触发“ Loaded”动作以使用HTTP响应填充商店。

例如,如果我派遣:

  

动作“ [要求]土豆请求”

它将发出HTTP请求:

  

HTTP GET /任何要求的马铃薯

然后将获得响应并进行调度:

  

操作“ [[Anything] Potatos Loaded””,以使用响应填充商店。

这意味着后端数据直接进入存储区,我不需要为每个“请求的”操作都编写@Effect。

如果异步元化约简是可能的话,这会简单得多,因为那样的话我就不需要“加载”动作,而是可以在原始“已请求”动作的有效负载降级之前对其进行修改。

这是主要的代码段:

@Effect()
requested$ = this.actions$.pipe(
  filter(action => action.type.endsWith('Requested')),
  map(action => ({
    action,
    path: getActionHttpPath(action),
    loadedAction: getLoadedAction(action)
  })),
  filter(obj => obj.loadedAction != null),
  tap(obj => debug('HTTP GET', obj.path)),
  mergeMap((obj) =>
    this.http.get(obj.path).pipe(
      map(res => ({...obj, res})),
      catchError(() => {
        return of({...obj, res: null})
      })
    )
  ),
  filter(obj => obj.res != null),
  map(obj => new obj.loadedAction(obj.res))
)