ngrx/data- 如何编写自定义减速器来处理返回多个实体的端点?

Mar*_*rkD 6 ngrx angular-ngrx-data

我目前正在尝试将我的 ngrx 存储转换为使用 ngrx/data 来处理我的实体。我遇到的更棘手的障碍之一是处理返回多个实体数据的 API 端点。一个简单的例子 - 假设我有以下模型可以从我的 API 中检索:

export interface Parent {
  id: string;
  name: string;
}

export interface Child {
  id: string;
  name: string;
  parent: string
}
Run Code Online (Sandbox Code Playgroud)

我有以下端点:

/api/parents              #GET (list of parents), POST (create new parent)
/api/parents/<PARENT_ID>  #GET, PATCH, PUSH, DELETE (a single parent)
/api/children             #GET (list of children), POST (create new child)
/api/children/<CHILD_ID>  #GET, PATCH, PUSH, DELETE (a single child)
/api/families             #GET (all parents and children)
Run Code Online (Sandbox Code Playgroud)

/api/families 是一个方便的函数,它以以下格式返回所有父级和子级:

/api/parents              #GET (list of parents), POST (create new parent)
/api/parents/<PARENT_ID>  #GET, PATCH, PUSH, DELETE (a single parent)
/api/children             #GET (list of children), POST (create new child)
/api/children/<CHILD_ID>  #GET, PATCH, PUSH, DELETE (a single child)
/api/families             #GET (all parents and children)
Run Code Online (Sandbox Code Playgroud)

过去,我families为我的 ngrx 存储创建了一个单独的条目,仅包含加载/加载参数,然后是一组LoadFamilies从服务器获取数据的操作。然后,我将这些操作包含在我的Parents 和Children 存储reducers 中,并适当地对它们进行操作。我现在想要做的是将这个额外的 reducer 添加到我现有的 ngrx/data 控制实体中。关于如何解决这个问题的任何想法/示例代码?

And*_*len 2

扩展DefaultDataService请参阅https://ngrx.io/guide/data/entity-dataservice#custom-entitydataservice

\n\n

在管道映射中将数据嵌套到实体(我使用normalizr)

\n\n

然后根据您认为合适的情况调度实体缓存操作EntityActionFactory as eaFactory来更新存储

\n\n

带有 Parent <--> ConcreteRecordHeader <--> ConcreteRecordLoad 的子级的示例

\n\n
  getById(key: string | number): Observable<ConcreteRecordHeader> {\n    return super.getById(key).pipe(\n      map((denorm: any) =>\n        this.categoryCacheService.normalizeCategory([denorm])\n      ),\n      tap((norm: NormalizedCategories) => this.mergeQuerySet(norm)),\n      map((norm: NormalizedCategories) => this.pickEntities(norm)[0])\n    ) as Observable<ConcreteRecordHeader>;\n  }\n\n  protected mergeQuerySet(norm: NormalizedCategories) {\n    console.log("\xe2\x9a\xa0\xef\xb8\x8f Merging server data \xe2\x9a\xa0\xef\xb8\x8f");\n    const options: EntityActionOptions = {\n      mergeStrategy: MergeStrategy.PreserveChanges\n    };\n    const data = norm.entities.concreteRecordLoads\n      ? Object.values(norm.entities.concreteRecordLoads)\n      : [];\n    const action = this.eaFactory.create(\n      "ConcreteRecordLoad",\n      EntityOp.SAVE_UPSERT_MANY_SUCCESS,\n      data,\n      options\n    );\n    this.entityCacheDispatcher.dispatch(action);\n  }\n\n  protected pickEntities(norm: NormalizedCategories) {\n    return (norm.entities.concreteRecordHeaders\n      ? Object.values(norm.entities.concreteRecordHeaders)\n      : []) as ConcreteRecordHeader[];\n  }\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

遗憾的this.entityCacheDispatcher.mergeQuerySet()是,无法使用 mergeStrategy,这是自然使用的 API。我计划为此提交 PR。

\n