@ngrx/data - 如何扩展集合缩减器/替换数据服务调用结果的处理?

@ngrx/data - how can I extend a collection reducer / replace handling of the results of a data service call?

使用 @ngrx/data 我想以不同于默认方式处理 getWithQuery API 调用的结果。

当前 if 这个 returns 实体数组,它直接加载到 entityCache 中。

到目前为止,我使用了 overview 中显示的标准模式:

export const entityMetadata: EntityMetadataMap = {
  PurchaseOrder: {}
};
@Injectable({
  providedIn: "root"
})
export class PurchaseOrderService extends EntityCollectionServiceBase<
  PurchaseOrder
> {
  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super("PurchaseOrder", serviceElementsFactory);
  }
}

相反 我想处理以下 API 响应并像正常 getWithQuery 一样在 entityCache 中加载 entities 但也将 total 贴在我商店的其他地方。

{
    "entities": [{...}, {...}, ..., {...}],    // list of entities
    "total": 100
}

如果返回此 API 响应,我自然会收到以下错误:

我的理解是,为每个提供 EntityCollectionDataService 接口和 add / delete / getAll / getById / getWithQuery / update 方法的实体创建并注册默认的 reducer。

我想保留这些方法但覆盖 getWithQuery reducer 以实现我的目标。

这个在Customizing Entity Reducer Behavior

中有提到

But quite often you'd like to extend a collection reducer with some additional reducer logic that runs before or after.

这到底是怎么做到的?

如果我尝试在 PurchaseOrderService

中覆盖 getWithQuery,我仍然会收到上述错误
  getWithQuery(params) {
    return super.getWithQuery(params).pipe(tap(result => console.log(result)));
  }

设法使用自定义 EntityDataService

使它正常工作
@Injectable()
export class PurchaseOrderDataService extends DefaultDataService<
  PurchaseOrder
> {
  constructor(
    http: HttpClient,
    httpUrlGenerator: HttpUrlGenerator,
    logger: Logger,
    config: DefaultDataServiceConfig
  ) {
    super("PurchaseOrder", http, httpUrlGenerator, config);
  }

  getWithQuery(params: string | QueryParams): Observable<PurchaseOrder[]> {
    return super.getWithQuery(params).pipe(
      tap(res => console.log(res)),
      map((res: any) => res.entities)
    );
  }
}

那么这个需要注册:

@NgModule({
  providers: [PurchaseOrderDataService] // <-- provide the data service
})
export class EntityStoreModule {
  constructor(
    entityDataService: EntityDataService,
    purchaseOrderDataService: PurchaseOrderDataService
  ) {
    entityDataService.registerService(
      "PurchaseOrder",
      purchaseOrderDataService
    ); // <-- register it
  }
}

并将其与 EntityDataModule.forRoot({ entityMetadata }),

一起导入