gpt4 book ai didi

angular - 覆盖 NGRX DefaultPersistenceResultHandler 的 handleSuccess

转载 作者:行者123 更新时间:2023-12-04 02:38:26 26 4
gpt4 key购买 nike

我在使用@ngrx/data 时遇到了一些困难,希望你们中的一位天才可以帮助我。

我有一个实体集合,想存储一些额外的信息以减少到服务器的往返次数并减少冗余加载。我有一个数据表,一次只想将一页加载到实体集合中,为了能够做到这一点,我想向我的集合中添加额外的元数据,以便我知道何时加载更多数据。例如。当我到达加载数据的末尾时加载更多(分页需要知道存在多少记录以及已加载多少记录)。

根据documentation我可以添加 additionalCollectionState 但需要一些更新新状态属性的方法。

我想我会复制/粘贴他们作为基础的示例代码并修改它以反射(reflect)我自己的属性。问题是我立即在 =>Action

Generic type 'Action' requires 1 type argument(s)

export class AdditionalPersistenceResultHandler  extends DefaultPersistenceResultHandler {

handleSuccess(originalAction: EntityAction): (data: any) => Action {
const actionHandler = super.handleSuccess(originalAction);
// return a factory to get a data handler to
// parse data from DataService and save to action.payload
return function(data: any) {
const action = actionHandler.call(this, data);
if (action && data && data.foo) {
// save the data.foo to action.payload.foo
(action as any).payload.foo = data.foo;
}
return action;
};
}
}

我也不确定这是否是解决此问题的正确方法,或者我是否正在解决这个问题太复杂了,我可以“简单地”以某种方式手动更新附加集合状态(在我的数据服务调用 getWithQuery() 中)并且如果是这样,最好/推荐的方法是什么。

干杯和感谢

加里

更新

在 Andrew 指出我明显的导入错误后,我现在已经实现了结果处理程序但出现以下错误

ERROR in Error during template compile of 'AdditionalPropertyPersistenceResultHandler'
Class AdditionalPropertyPersistenceResultHandler in D:/dev/angular/ng-vet/src/app/treatments/services/treatments-entity-result-handler.ts extends from a Injectable in another compilation unit without duplicating the decorator
Please add a Injectable or Pipe or Directive or Component or NgModule decorator to the class.

考虑到 stackblitz 这没有任何意义没有它,但效果很好。

我的实体元数据映射

const entityMetadata: EntityMetadataMap = {
TreatmentTemplate: {
entityDispatcherOptions: {
optimisticUpdate: true
}
},
Treatment: {
additionalCollectionState: {
totalRecords: 0
},
entityDispatcherOptions: {
optimisticUpdate: true
}
}
};

和提供者:

providers: [
TreatmentsDataService,
TreatmentEntityService,
TreatmentTemplateResolver,
TreatmentTemplatesDataService,
TreatmentTemplateEntityService,
{
provide: PersistenceResultHandler,
useClass: AdditionalPropertyPersistenceResultHandler
},
{
provide: EntityCollectionReducerMethodsFactory,
useClass: AdditionalEntityCollectionReducerMethodsFactory
}
]

我基本上是从 stackblitz 中复制粘贴的方法..

在 ^8.0.2 of angular 和 ^8.6.0 of ngrx 这可能是问题吗?

最佳答案

使用 additionalCollectionState 有一个注意事项。

默认的 QUERY_MANY_SUCCESS reducer 期望 action.payload.data 是一个实体数组,但 QUERY_MANY 操作 action.payload.data 将是 api 返回的任何内容。

说它返回

interface QueryManyAPIResponse<T> {
total: number,
entities: T[]
}

您可以将属性 total 添加到操作负载,但 action.payload.data 需要是实体。

@Injectable()
export class AdditionalPersistenceResultHandler extends DefaultPersistenceResultHandler {

handleSuccess(originalAction: EntityAction): (data: any) => Action {
const actionHandler = super.handleSuccess(originalAction);

return function(data: any) {
/** Default success action */
const successAction = actionHandler.call(this, data);

/** Change payload for query many */
if (successAction && data && data.total) {
(successAction as any).payload.total = data.total;
}
if (successAction && data && data.entities) {
(successAction as any).payload.data = data.entities;
}

return action;
};
}
}

这只是对操作进行更改。

虽然默认的 reducer 会处理实体,但 NgRx Docs 的第 2 步和第 3 步需要将总数作为属性添加到实体集合中。


pagination would need to know how many records exist and how many have been loaded

已加载的数量是可推导的(id.length,因此您可以为此使用选择器),因此不需要保存在商店中。

I have an entity collection and would like to store some additional information to reduce round trips to the server and also reduce redundant loading.

这是一个难题。我发现减少 api 调用的最干净、最直接的方法是使用服务器端分页表(请参阅下面的引用资料)并在表之前提供一个页面,该页面提供带有各种统计信息的仪表板(需要实现此 API)内置查询参数的过滤器和指向表格页面的链接。

如果数据已经在第 1 页,很少有人会花时间在分页的 mat 表中进行分页。
没有人愿意。

dashboard.component.html

        <button
mat-raised-button
[routerLink]="['/procurement/orders']"
[queryParams]="{ awaitingPrices: 'yes', employeeID: userID }"
>
{{ statistics.awaitingPricesUser }}
</button>

orders.component.html(容器)

<app-order-find (filter)="onFilter($event)"></app-order-find>
<app-order-filters
[suppliers]="suppliers$ | async"
[employees]="employees$ | async"
[filters]="filters"
(filtersUpdate)="updateFilters($event)"
></app-order-filters>
<app-orders-table
[totalNumberOfOrders]="totalNumberOfOrders$ | async"
[filters]="filters"
(review)="onReview($event)"
(edit)="onEdit($event)"
(delete)="onDelete($event)"
>
></app-orders-table
>

备选方案

您是否希望将所有数据加载到商店中,即在后台加载第 1、2、...、最后一页的分页数据。加载所有数据后,您可以完全通过选择器进行客户端分页。

如果您希望在表和详细信息 View 之间来回切换,或者在相同页面和相同过滤器上来回切换,您可以保留 { urlWithQueryParams: entityIds } 的缓存映射并使用选择器来获取从商店。如果删除相关实体,则需要丢弃这些。

引用资料

服务器端分页表 - https://blog.angular-university.io/angular-material-data-table/

关于angular - 覆盖 NGRX DefaultPersistenceResultHandler 的 handleSuccess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60543031/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com