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

Posted

技术标签:

【中文标题】在ngrx/effect中访问存储的正确方法【英文标题】:Proper way to access store in ngrx/effect 【发布时间】:2018-11-17 20:13:13 【问题描述】:

我正在使用 Angular 6、ngrx/store、ngrx/effects。 当我按下“保存”按钮时,我有一个应该触发的效果。我在那里使用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。 我究竟做错了什么?可能我应该使用另一个运营商 insted withLatestFrom 或者解决方案是什么?谢谢

附:顺便说一句,我每次想从商店获取一些数据时都使用withLatestFrom。对吗?

【问题讨论】:

您可以编写一个选择器来获取所有数据。或者,您可以将所需的所有数据作为有效负载发送。 您可能正在寻找解决方案。 medium.com/@viestursv/… 【参考方案1】:

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

【讨论】:

【参考方案2】:

您需要在saveAll 被触发之前触发操作handleItemsChanges。一种方法是在handleItemsChanges 操作上创建效果并触发save 操作。

框架会保证执行顺序(先handleItemsChangessave),这样withLatestFrom的操作就会如你所愿。

【讨论】:

以上是关于在ngrx/effect中访问存储的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

Cordova + ngrx/effect fire and forget long running 方法冻结 UI

如何在ngrx/effect(redux-observable)中调度多个动作?

Angular 5 ngrx Effect 没有导出成员'ofType'

NgRx @Effect 与 createEffect

如何处理来自 ngrx effect 的 catch 块的错误并将其发送到组件中?

ngrx effect 多次调用observer,但只调度了一个action