使用withLatestFrom调用它甚至ofType(action)的效果未被触发

时间:2018-06-01 12:51:43

标签: javascript angular ngrx ngrx-store ngrx-effects

我正在使用Angular 5,ngrx / store。我有一个影响:

@Effect()
  updateAfterChanges$ = this.actions$.pipe(
    ofType(ActionTypes.ChangesInItems),
    withLatestFrom(
      this.store.select(fromReducers.getItemsList)
    ),
    switchMap(([action, itemsList]: [ActionType, Items[]]) => {
       return [new UpdateItems()]
    })
)

getItemsList看起来像这样:

export const getItemsList= createSelector(
  fromAnotherReducer.getAllItems,
  getCurerntItemdId,
  (allItems, itemId) => collectItems(allItems, allItems[itemId].subItems)
);

这个选择器绝对是另一个页面 - page1。我根本没有物品的地方。当我在page2上打开模型窗口时,将从服务器加载项目。 因此,page1我收到错误Cannot read property 'subItems' of undefined。为什么这个选择器甚至不会在ofType(ActionTypes.ChangesInItems)之后调用?我必须添加一个检入选择器:

Object.keys(allItems).length !== 0 ?
    collectItems(allItems, allItems[itemId].subItems) : []

为什么会这样?我不想在每个使用动态加载数据的选择器中添加检查。我希望只有在回复ofType(ActionTypes.ChangesInItems)

时才会调用该效果

3 个答案:

答案 0 :(得分:1)

在此处使用时,withLatestFrom将始终执行。您不需要逻辑来检查项目,稍微调整一下结构:

@Effect()
updateAfterChanges$ = this.actions$.pipe(
  ofType(ActionTypes.ChangesInItems),
  switchMap(action => {
    return this.store.pipe(
      select(fromReducers.getItemsList),
      map(items => {
        return [new UpdateItems()]
      }),
    );
  }),
)

答案 1 :(得分:1)

尽管bc1105 answer简化了您的用例并运行良好,但我会回答您的问题,如果它对其他人有用(并且似乎很难找到),尤其是当您想将多个选择器与{{1 }}。


为避免在withLatestFrom中使用的withLatestFrom被自动触发,但只有在分派动作后,您才需要在@Effect内部使用它。

这是您的代码调整了...

switchMap

答案 2 :(得分:0)

这是一种预期的行为,它是 withLatestFrom 的工作方式,因此它将开始立即监听给定的可观察的 ,但是仅在发出源时才会发出该值。 !

example将说明正在发生的事情:

因此test()内的console.log将立即显示,但是test()的返回值仅在触发点击事件时显示