如何使用实体效果扩展ngrx /数据?

问题描述 投票:1回答:1

[转换应用程序以使用ngrx状态管理时,我决定通过EntityMaps使用ngrx / data管理某些模型的状态。到目前为止,这仍然可以正常工作,但是当事情变得更加复杂时,例如基于从远程服务器上获取的模型数据,我需要相关模型(订单->产品或REST端点格式GET orders/:id/products

[我感到停滞-我知道有ngrx / effects可以触发使用ngrx时加载其他数据的操作,在此ngrx/data guide中,`EntityEffects被提到可以触发操作带来的副作用,但是文档似乎并非如此进行中,现在对我没有太大帮助。

不幸的是,扩展EntityEffects以自定义远程数据的获取并没有太多好处。当然,我可以一路下实现选择器,动作,缩减器,以标准的ngrx方式实现效果,但这不是ngrx / data的全部要点,以更少的样板代码简化状态处理并充当包装器在ngrx周围,隐藏了默认/样板代码,但仍提供使用基础部件的方法?

由于我通常对ngrx和状态管理还比较陌生,所以我不知道在哪里确切寻找最佳实践或推荐的解决方案,如何解决此问题。

所以我的问题基本上是:

  1. 我如何同时使用ngrx / data和加载(相关的)模型数据以及ngrx / effects或EntityEffects?
  2. 我在哪里扩展适当的服务/类,而不必手动执行每个化简器/操作,而是让ngrx / data来解决这一问题?

我已经搜索过Stackoverflow,Gitter和问过的同事,但是没有成功-还是我使它变得比必须的更加复杂?如果是这样,我非常感谢您的帮助。

注意:这个问题尤其是关于ngrx /

angular ngrx-effects angular-ngrx-data ngrx-data
1个回答
0
投票

这是一个开放的github问题https://github.com/ngrx/platform/issues/1934


但是我相信有一种方法可以使用EntityCacheDispatcher的saveEntities方法Save with EntityCacheDispatcher.saveEntities()从头开始,而无需完全从头开始。

为了让您了解如何按预期使用它,这是我对最近项目的保存订单效果

  saveOrder$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PurchaseOrderActions.saveOrder),
      switchMap(() => {
        const order$ = this.store.pipe(select(selectHeader));
        const orderLines$ = this.store.pipe(select(allLines));
        const deletedOrderLines$ = this.store.pipe(select(selectDeletedLines));
        return combineLatest([order$, orderLines$, deletedOrderLines$]).pipe(
          first(),
          switchMap(([order, lines, deletedLines]) => {
            const changes: ChangeSetItem[] = [
              cif.upsert("PurchaseOrder", order),
              cif.upsert("PurchaseOrderLine", lines),
              cif.delete("PurchaseOrderLine", deletedLines)
            ];
            return this.entityCacheDispatcher
              .saveEntities(changes, `${this.baseURL}order`)
              .pipe(
                map(changesResponse =>
                  PurchaseOrderActions.saveOrderSuccess({
                    header: changesResponse.changes[0]
                      .entities[0] as PurchaseOrder,
                    lines: changesResponse.changes[1]
                      .entities as PurchaseOrderLine[]
                  })
                )
              );
          })
        );
      })
    )
  );

潜在路线图

  1. [创建您的自定义操作,例如输入"[OrderProductsPage ONINIT] ONINIT"
  2. 创建调用saveEntities的效果
// include in custom action payload and get this id here
const id; 

// changeSet with empty changes
const changeSet = {
    changes: [],
    tag: "CUSTOM_GET_PRODUCTS" // hook for defining custom behaviour
}
this.entityCacheDispatcher.saveEntities(changeSet, `orders/${id}/products`)
  1. 扩展EntityCacheDataService并覆盖saveEntities方法,首先检查标记是否为CUSTOM_GET_PRODUCTS,否则调用super.saveEntities(changeSet,url)。如果标签是CUSTOM_GET_PRODUCTS,则调用获取http和管道映射以使用ChangeSetOperation.Add
  2. 更改集

参考super.saveEntities()

更新

这有效,但是比我想要的要难一些

Stackblitz

© www.soinside.com 2019 - 2024. All rights reserved.