我在使用 @ngrx/data 时遇到了一些困难,希望你们中的一位天才可以帮助我。
我有一个实体集合,想存储一些额外的信息,以减少到服务器的往返次数并减少冗余负载。我有一个数据表,并且只想一次将一页加载到实体集合中,为了能够做到这一点,我想向我的集合中添加额外的元数据,以便我知道何时加载更多数据。例如,当我到达加载数据的末尾时加载更多(分页需要知道存在多少条记录以及加载了多少条记录)。
根据文档,我可以添加 additionalCollectionState 但需要某种方式来更新新的状态属性。
我想我会复制/粘贴他们作为基础的示例代码并修改它以反映我自己的属性..问题是我立即在 => Action上收到打字稿错误
通用类型“操作”需要 1 个类型参数
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;
};
}
}
Run Code Online (Sandbox Code Playgroud)
我也不确定这是否是解决此问题的正确方法,或者我是否将其处理得太复杂,我是否可以“简单地”以某种方式手动更新额外的集合状态(在我的数据服务调用 getWithQuery() 中),如果是这样呢?将是最好的/推荐的方法。
干杯和感谢
加里
更新
在安德鲁指出我明显的导入错误之后,我现在已经实现了结果处理程序,但出现以下错误
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.
Run Code Online (Sandbox Code Playgroud)
考虑到stackblitz没有它并且它工作得很好,这没有任何意义。
我的 entityMetadataMap
const entityMetadata: EntityMetadataMap = {
TreatmentTemplate: {
entityDispatcherOptions: {
optimisticUpdate: true
}
},
Treatment: {
additionalCollectionState: {
totalRecords: 0
},
entityDispatcherOptions: {
optimisticUpdate: true
}
}
};
Run Code Online (Sandbox Code Playgroud)
和提供者:
providers: [
TreatmentsDataService,
TreatmentEntityService,
TreatmentTemplateResolver,
TreatmentTemplatesDataService,
TreatmentTemplateEntityService,
{
provide: PersistenceResultHandler,
useClass: AdditionalPropertyPersistenceResultHandler
},
{
provide: EntityCollectionReducerMethodsFactory,
useClass: AdditionalEntityCollectionReducerMethodsFactory
}
]
Run Code Online (Sandbox Code Playgroud)
我基本上复制粘贴了stackblitz中的方法..
在 ^8.0.2 的角度和 ^8.6.0 的 ngrx 可能是问题吗?
使用additionalCollectionState.
默认的 QUERY_MANY_SUCCESS 减速器期望action.payload.data是一个实体数组,但 QUERY_MANY 操作action.payload.data将是 api 返回的任何内容。
说它回来了
interface QueryManyAPIResponse<T> {
total: number,
entities: T[]
}
Run Code Online (Sandbox Code Playgroud)
您可以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;
};
}
}
Run Code Online (Sandbox Code Playgroud)
这只是对操作进行更改。
虽然默认的 reducer 会处理实体,但需要NgRx Docs的第 2 步和第 3 步将总数作为属性添加到实体集合中。
分页需要知道有多少记录存在以及有多少已加载
已加载的数量是可推导出的(id.length,因此您可以为此使用选择器),因此不需要保存在商店中。
我有一个实体集合,想存储一些额外的信息,以减少到服务器的往返次数并减少冗余负载。
这是一个很难的问题。我发现减少 api 调用的最干净、最直接的方法是使用服务器端分页表(请参阅下面的参考资料)并在表之前提供一个页面,该页面提供一个带有统计信息的仪表板(需要实现此 API),其中包含各种过滤器和链接到带有内置查询参数的表格页面。
如果数据已经在第 1 页上,很少有人会花时间在分页的 mat 表中进行分页。
而且没有人愿意。
仪表板.component.html
<button
mat-raised-button
[routerLink]="['/procurement/orders']"
[queryParams]="{ awaitingPrices: 'yes', employeeID: userID }"
>
{{ statistics.awaitingPricesUser }}
</button>
Run Code Online (Sandbox Code Playgroud)
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
>
Run Code Online (Sandbox Code Playgroud)
您是否希望将所有数据加载到存储中,即在后台加载第 1、2、...、最后一页的分页数据。加载所有数据后,您可以完全通过选择器进行客户端分页。
如果您希望在表格和详细信息视图之间来回切换,或者在相同页面和相同过滤器上来回切换,您可以保留缓存映射{ urlWithQueryParams: entityIds }并使用选择器从商店获取。如果您删除相关实体,则需要将它们扔掉。
服务器端分页表 - https://blog.angular-university.io/angular-material-data-table/
| 归档时间: |
|
| 查看次数: |
454 次 |
| 最近记录: |