NGRX 效果中的 concatLatestFrom 循环

concatLatestFrom loop inside NGRX effect

我有 orders/order 个项目,它们被组织在 schedules/schedule 个项目中。每个订单项目对应1+个计划项目。

我有一个功能可以让用户批准(或不批准)一个计划项目,这也会导致与同一订单项目相关的所有其他计划项目得到批准。批准一个项目可能会导致相应的计划被重新排序。

在实际将计划项目设置为已批准之前,我需要进行时间戳检查以确保用户正在处理最新数据。一般的工作流程是将所有 'affected entities' 与相应的 http 请求一起传递。

我现在正在努力的是在我的影响范围内从 NGRX 存储中获取所有受影响的实体,特别是我需要获取

我有这些选择器:

export const getScheduleById = (id: number) =>
  createSelector(getScheduleEntities, (entities) => entities[id]);

export const getScheduleItemsForSchedule = (scheduleId: number) =>
  createSelector(getScheduleItemsAlls, (all) => all.filter(x => x.id === scheduleId));

export const getOtherSchedulesForOrderItem = (scheduleItem) => 
  createSelector(getScheduleItemsAlls, (all) => all.filter(x => x.orderItemId === scheduleItem.orderItemId));

我的(不完整的)效果看起来像这样(已批准:布尔值):

approveItem$ = createEffect(() =>
  this.actions$.pipe(
    ofType(scheduleItemActions.approveItem),
    concatMap(({ item, approved }) =>
      of({ item, approved }).pipe(
        concatLatestFrom(() => [
          this.store.select(scheduleItemSelectors.getOtherSchedulesForOrderItem(item)),
          this.store.select(scheduleSelectors.getScheduleById(item.scheduleId)),
          this.store.select(scheduleItemSelectors.getScheduleItemsForSchedule(item.scheduleId))
        ]),

        // At this point I would need to do a concatLatestFrom store.select with 'getScheduleById'  
        // and 'getScheduleItemsForSchedule' for all 'splitItems', but I don't know how to that.
        // Subsequent map etc. has to be adjusted of course:
        // I'd combine down to ({ item, approved, allSchedules*, allScheduleItems* })
        // *Separated since right know I distinguish 'object type' in code, not by property and interfaces only exist during dev time.

        map(([{ item, approved }, splitItems, itemSchedule, itemScheduleItems]) =>
          ({ item, approved, splitItems, itemSchedule, itemScheduleItems })
        )
      )
    ),
    switchMap(({ item, approved, splitItems, itemSchedule, itemScheduleItems }) => {
      let affectedEntities: AffectedEntity[] = /* just builds a list with subset-information of the entities (object type, id, timestamp) */

      return this.scheduleItemService.approveItem(item, approved, affectedEntities).pipe(...); 
    })
  )
);

我对 rxjs 运算符还不太熟悉,这个让我很难过。

非常感谢帮助 and/or 涵盖类似内容的资源(我找不到任何东西,但我也不知道有什么好的关键字来搜索这个)。

因此,根据评论,我将逻辑移至单独的选择器。

现在看起来有点像:

选择器:

export const getApproveAllSchedules = (item: ScheduleItem) =>
  createSelector(
    getScheduleAll,
    scheduleItemSelectors.getScheduleItemsForOrderItem(item.orderItemId),
    (all, splitItems) => {
      let scheduleIds = splitItems.map((o) => o.scheduleId);
      return all.filter((x) => scheduleIds.indexOf(x.id) > -1);
    }
  );

//---

export const getApproveAllScheduleItems = (item: ScheduleItem) =>
  createSelector(
    getScheduleItemAll,
    getScheduleItemsForOrderItem(item.orderItemId),
    (all, splitItems) => {
      let schedules = splitItems.map((o) => o.scheduleId);
      return all.filter((x) => schedules.indexOf(x.id) > -1);
    }
  );

效果:

approveItem$ = createEffect(() =>
    this.actions$.pipe(
      ofType(scheduleItemActions.approveItem),
      concatLatestFrom(({ item, approved }) => [
         this.store.select(scheduleSelectors.getApproveAllSchedules(item)),
         this.store.select(scheduleItemSelectors.getApproveAllScheduleItems(item)),
      ]),
      switchMap(([{ item, approved }, schedules, scheduleItems]) => {
        let affectedEntities: AffectedEntity[] = /* just builds a list with subset-information of the entities (object type, id, timestamp) */

        return this.scheduleItemService.approveItem(item, approved, affectedEntities).pipe(...);
      })
    )
  );