@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 }),
一起导入
使用 @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 }),