在ngrx / effect中访问存储的正确方法

时间:2018-06-07 19:54:37

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

我正在使用Angular 6,ngrx / store,ngrx / effects。 当我按下" Save"我有一个应该被触发的效果。按钮。我在那里使用withLatestFrom来收集将其发送到服务器所需的所有数据:

@Effect({dispatch: false})
  saveAll$ = this.actions$.pipe(
    ofType(ActionTypes.Save),
    withLatestFrom(
      this.store.select(fromReducers.getData1),
      this.store.select(fromReducers.getData2),
      this.store.select(fromReducers.getData3),
      this.store.select(fromReducers.getData4)
    ),
    switchMap(([action, data1, data2, data3, data4]: [ActionType, Data1[], Data2[], Data3[], Data4[]]) => {
       // here is some operations with these data
       return this.apiService.saveData({data1, data2, data3, data4})
    })
)

以下是getData1选择器:

export const getData1= createSelector(
  getItems,
  getIndexes,
  (items, indexes) => {
    console.log('HI, I AM getData1');
    return transformItems(items, indexes);
  }
);
反过来,

getItems会返回state.items。问题是state.items可以在另一种效果中修改:

@Effect()
  handleItemsChanges$ = this.actions$.pipe(
    ofType(ActionTypes.ChangesInItems),
    withLatestFrom(
      this.store.select(fromReducers.getItems),
      this.store.select(fromReducers.getUsers),
    ),
    switchMap(([action, items, users]: [ActionType, Item[], User[]]) => {
       console.log('I AM handleItemsChanges');
       const actions = [];
       if (itemsShouldBeUpdated) {
          actions.push(new UpdateData(changes))
       }
    })
)

所以getData1选择器从商店获取数据取决于另一个名为handleItemsChanges的效果。每次更改与项目相关的内容并再次重新生成时,都会触发handleItemsChanges效果。 因此,在saveAll中我得到的不是state.items。 我究竟做错了什么?也许我应该使用withLatestFrom的另一个操作员或者解决方案是什么?谢谢

P.S。顺便说一下,每当我想从商店获取一些数据时,我都会使用withLatestFrom。这是对的吗?

2 个答案:

答案 0 :(得分:0)

您需要先触发handleItemsChanges,然后才能触发saveAll。一种实现方法是对handleItemsChanges动作产生影响并触发save动作。

该框架将保证执行顺序(先执行handleItemsChanges,然后执行save),这样withLatestFrom操作将按预期工作。

答案 1 :(得分:0)

我在ngrx github上找到了讨论:https://github.com/ngrx/platform/issues/467 看起来我们有2个丑陋的变体,现在可以从效果中访问商店。