在将应用程序转换为使用 ngrx 状态管理时,我决定通过 EntityMaps 使用 ngrx/data 管理某些模型的状态。到目前为止这工作正常,但是当事情变得有点复杂时,例如基于从远程服务器获取的模型数据,我需要相关模型(订单->产品或 REST 端点格式 GET orders/:id/products
)
我觉得卡住了 - 我知道有 ngrx/effects 可以触发在使用 ngrx 时加载其他数据的操作,并且在此 ngrx/data guide , `EntityEffects 被提到会触发 Action 的副作用,但除此之外,文档似乎还在进行中,现在对我帮助不大。
不幸的是,没有太多关于扩展 EntityEffects 以自定义远程数据获取的内容。当然,我可以一路向下实现选择器、 Action 、缩减器、影响标准的 ngrx 方式,但 ngrx/data 的全部意义在于用更少的样板代码使状态处理更容易,并充当包装器围绕 ngrx,隐藏默认/样板代码但仍然提供使用底层部分的方法?
由于我对 ngrx 和一般的状态管理还比较陌生,所以我不知道去哪里寻找最佳实践或推荐的解决方案,以及如何处理这个问题。
所以我的问题基本上是:
- 我如何才能同时使用 ngrx/data 并通过 ngrx/effects 或 EntityEffects 加载(相关)模型数据?
- 我在哪里扩展适当的服务/类,而不必手动实现每个 reducer/action,而是让 ngrx/data 来处理?
我已经搜索了 Stackoverflow、Gitter 并询问了同事,但都没有成功 - 或者我是否让它变得比它必须的更复杂?如果是这样,我感谢您的帮助。
注意:这个问题特别针对ngrx/
最佳答案
这是一个开放的 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[]
})
)
);
})
);
})
)
);
潜在路线图
- 创建您的自定义操作,例如输入
[OrderProductsPage ONINIT] ONINIT"
- 创建调用 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`)
- 扩展
EntityCacheDataService
并覆盖saveEntities
方法以首先检查标签是否为CUSTOM_GET_PRODUCTS
否则调用 super.saveEntities(changeSet, url)。如果标签是CUSTOM_GET_PRODUCTS
,则调用 get http 并将管道映射到带有ChangeSetOperation.Add
的 changeSet
更新
这行得通,但它比我想要的更 hacky
Stackblitz
关于angular - 如何使用 Entity Effects 扩展 ngrx/data?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60256840/