PrimeNG TurboTable - 奇怪的虚拟滚动行为 - 不断加倍 event.rows
PrimeNG TurboTable - strange virtual scroll behaviour - keeps doubling event.rows
我已经实现了一个使用 PrimeNG TurboTable 和 NgRx 的自定义网格组件,并且我已经使用内置的 TurboTable 虚拟滚动向它添加了虚拟滚动功能。它也是延迟加载,带有 onLazyLoad
处理程序。但是,当我在滚动网格结果时调用 onLazyLoad
时,我得到了这种奇怪的行为。
onLazyLoad called with event.first=0 and event.rows=40
onLazyLoad called with event.first=0 and event.rows=80
onLazyLoad called with event.first=0 and event.rows=160
onLazyLoad called with event.first=0 and event.rows=320
onLazyLoad called with event.first=0 and event.rows=640
onLazyLoad called with event.first=0 and event.rows=1280
所以有两个问题:
event.first
始终为 0
event.rows
一直翻倍到很
高值
我认为这是 PrimeNG 中的错误,但当我尝试使用简单的 StackBlitz 重现它时,它的行为是正确的。
https://stackblitz.com/edit/github-primeng-virtualscroll-issue
我在 StackBlitz 上看到了这个:
loadDataOnScroll is called with event.first=0 and event.rows=40
loadDataOnScroll is called with event.first=20 and event.rows=40
loadDataOnScroll is called with event.first=40 and event.rows=40
loadDataOnScroll is called with event.first=80 and event.rows=40
loadDataOnScroll is called with event.first=120 and event.rows=40
所以 event.rows
保持不变,event.first
正常增加。
我使用 TurboTable 的方式似乎触发了此问题,但我不知道是什么。可能是什么问题?
这是我的网格组件中的相关代码:
延迟加载处理程序:
onLazyLoad(event: LazyLoadEvent) {
// TODO - In this StackBlitz it behaves correctly
// https://stackblitz.com/edit/github-primeng-virtualscroll-issue
console.log(
`onLazyLoad called with event.first=${event.first} and event.rows=${
event.rows
}`
);
// TODO - This state should be handled by NgRx as well.
this.loading = true;
this.filters = {};
const hasPagination = this.settings.features.Pagination;
// TODO - Tweak the behavior of virtual scroll skipCount/maxResultCount
// based on testing results.
// The default behavior is a bit strange, skipCount is always 0
// and maxResultCount keeps getting doubled.
let pageSize = event.rows ? event.rows : GridConfig.PageSize;
this.filters.maxResultCount = pageSize;
this.filters.skipCount = event.first ? event.first : 0;
this.filters.ignorePagination = !hasPagination;
if (event.sortOrder && event.sortField) {
const sortingDirection = event.sortOrder > 0 ? 'ASC' : 'DESC';
this.filters.sorting = event.sortField + ' ' + sortingDirection;
}
if (event.globalFilter) {
this.filters.filter = event.globalFilter;
}
if (event.filters) {
this.filters.columnFilters = this.buildColumnFilters(event.filters);
}
this.filters.parentFilters = this.parentFilters; // this works only with client-side caching & filtering
if (this.settings.features.ClientSideCaching) {
// Load only once
this.gridLoaded().subscribe(loaded => {
if (loaded) {
this.store.dispatch(
new this.settings.stateActions.FilterClientSide(
this.filters
)
);
}
});
} else {
this.store.dispatch(
new this.settings.stateActions.Read(this.filters)
);
}
}
我在模板中传入的参数:
<p-table
#dataTable
[value]="(data$ | async)?.items"
[loading]="loading"
[lazy]="true"
[virtualScroll]="!settings.features.Pagination"
[virtualRowHeight]="35"
[scrollable]="!settings.features.Pagination"
(onLazyLoad)="onLazyLoad($event)"
[autoLayout]="true"
[columns]="selectedColumns"
[paginator]="settings.features.Pagination"
scrollHeight="400px"
[resizableColumns]="true"
[rowsPerPageOptions]="[10, 20, 30]"
[totalRecords]="(data$ | async)?.totalCount"
[rows]="(this.settings.states.Search | async)?.maxResultCount"
[stateStorage]="this.settings.persistence?.stateStorage"
[stateKey]="this.settings.persistence?.stateKey"
[(selection)]="selectedRows"
[selectionMode]="this.settings.rowSelection?.selectionMode || null"
(onRowSelect)="onRowSelect($event)"
[dataKey]="this.settings.rowSelection?.dataKey || null"
>
任何帮助或想法将不胜感激!谢谢!
这可能是因为在 https://stackblitz.com/edit/github-primeng-virtualscroll-issue 中您有一个硬编码的总记录数参数 <p-table>
。
在您的实际实现中,您可能设置为小于您的数据集大小或 0 (看起来您在那里有一个可观察的。检查它的评估结果。尝试设置一些大于您的数据集的大数看看这个理论是否正确).
检查在 <p-table>
的实施中 [totalRecords]="(data$ | async)?.totalCount"
参数对您的评估是什么。
希望这会解决它。
问题的发生是因为 event.rows
一直保存在 NgRx 存储中,我在构建过滤器时重复使用它,每次 onLazyLoad
被调用时它都会加倍。
这里我用 NgRx 存储值初始化 rows
:
[rows]="(this.settings.states.Search | async)?.maxResultCount"
然后在 onLazyLoad
里面我用的是 event.rows
:
let pageSize = event.rows ? event.rows : GridConfig.PageSize;
this.filters.maxResultCount = pageSize;
PrimeNG 在他们的虚拟滚动代码中加倍 event.rows
,当我调用 FilterClientSide
操作时它会持久保存到 NgRx 存储中。然后模板获得该新值,并在随后的 onLazyLoad
中再次翻倍。
对我有用的解决方案是为此设置一个常量:
if (this.settings.features.VirtualScroll) {
pageSize = GridConfig.PageSize * 2;
} else {
pageSize = event.rows ? event.rows : 10;
}
我已经实现了一个使用 PrimeNG TurboTable 和 NgRx 的自定义网格组件,并且我已经使用内置的 TurboTable 虚拟滚动向它添加了虚拟滚动功能。它也是延迟加载,带有 onLazyLoad
处理程序。但是,当我在滚动网格结果时调用 onLazyLoad
时,我得到了这种奇怪的行为。
onLazyLoad called with event.first=0 and event.rows=40
onLazyLoad called with event.first=0 and event.rows=80
onLazyLoad called with event.first=0 and event.rows=160
onLazyLoad called with event.first=0 and event.rows=320
onLazyLoad called with event.first=0 and event.rows=640
onLazyLoad called with event.first=0 and event.rows=1280
所以有两个问题:
event.first
始终为 0event.rows
一直翻倍到很 高值
我认为这是 PrimeNG 中的错误,但当我尝试使用简单的 StackBlitz 重现它时,它的行为是正确的。 https://stackblitz.com/edit/github-primeng-virtualscroll-issue
我在 StackBlitz 上看到了这个:
loadDataOnScroll is called with event.first=0 and event.rows=40
loadDataOnScroll is called with event.first=20 and event.rows=40
loadDataOnScroll is called with event.first=40 and event.rows=40
loadDataOnScroll is called with event.first=80 and event.rows=40
loadDataOnScroll is called with event.first=120 and event.rows=40
所以 event.rows
保持不变,event.first
正常增加。
我使用 TurboTable 的方式似乎触发了此问题,但我不知道是什么。可能是什么问题? 这是我的网格组件中的相关代码:
延迟加载处理程序:
onLazyLoad(event: LazyLoadEvent) {
// TODO - In this StackBlitz it behaves correctly
// https://stackblitz.com/edit/github-primeng-virtualscroll-issue
console.log(
`onLazyLoad called with event.first=${event.first} and event.rows=${
event.rows
}`
);
// TODO - This state should be handled by NgRx as well.
this.loading = true;
this.filters = {};
const hasPagination = this.settings.features.Pagination;
// TODO - Tweak the behavior of virtual scroll skipCount/maxResultCount
// based on testing results.
// The default behavior is a bit strange, skipCount is always 0
// and maxResultCount keeps getting doubled.
let pageSize = event.rows ? event.rows : GridConfig.PageSize;
this.filters.maxResultCount = pageSize;
this.filters.skipCount = event.first ? event.first : 0;
this.filters.ignorePagination = !hasPagination;
if (event.sortOrder && event.sortField) {
const sortingDirection = event.sortOrder > 0 ? 'ASC' : 'DESC';
this.filters.sorting = event.sortField + ' ' + sortingDirection;
}
if (event.globalFilter) {
this.filters.filter = event.globalFilter;
}
if (event.filters) {
this.filters.columnFilters = this.buildColumnFilters(event.filters);
}
this.filters.parentFilters = this.parentFilters; // this works only with client-side caching & filtering
if (this.settings.features.ClientSideCaching) {
// Load only once
this.gridLoaded().subscribe(loaded => {
if (loaded) {
this.store.dispatch(
new this.settings.stateActions.FilterClientSide(
this.filters
)
);
}
});
} else {
this.store.dispatch(
new this.settings.stateActions.Read(this.filters)
);
}
}
我在模板中传入的参数:
<p-table
#dataTable
[value]="(data$ | async)?.items"
[loading]="loading"
[lazy]="true"
[virtualScroll]="!settings.features.Pagination"
[virtualRowHeight]="35"
[scrollable]="!settings.features.Pagination"
(onLazyLoad)="onLazyLoad($event)"
[autoLayout]="true"
[columns]="selectedColumns"
[paginator]="settings.features.Pagination"
scrollHeight="400px"
[resizableColumns]="true"
[rowsPerPageOptions]="[10, 20, 30]"
[totalRecords]="(data$ | async)?.totalCount"
[rows]="(this.settings.states.Search | async)?.maxResultCount"
[stateStorage]="this.settings.persistence?.stateStorage"
[stateKey]="this.settings.persistence?.stateKey"
[(selection)]="selectedRows"
[selectionMode]="this.settings.rowSelection?.selectionMode || null"
(onRowSelect)="onRowSelect($event)"
[dataKey]="this.settings.rowSelection?.dataKey || null"
>
任何帮助或想法将不胜感激!谢谢!
这可能是因为在 https://stackblitz.com/edit/github-primeng-virtualscroll-issue 中您有一个硬编码的总记录数参数 <p-table>
。
在您的实际实现中,您可能设置为小于您的数据集大小或 0 (看起来您在那里有一个可观察的。检查它的评估结果。尝试设置一些大于您的数据集的大数看看这个理论是否正确).
检查在 <p-table>
的实施中 [totalRecords]="(data$ | async)?.totalCount"
参数对您的评估是什么。
希望这会解决它。
问题的发生是因为 event.rows
一直保存在 NgRx 存储中,我在构建过滤器时重复使用它,每次 onLazyLoad
被调用时它都会加倍。
这里我用 NgRx 存储值初始化 rows
:
[rows]="(this.settings.states.Search | async)?.maxResultCount"
然后在 onLazyLoad
里面我用的是 event.rows
:
let pageSize = event.rows ? event.rows : GridConfig.PageSize;
this.filters.maxResultCount = pageSize;
PrimeNG 在他们的虚拟滚动代码中加倍 event.rows
,当我调用 FilterClientSide
操作时它会持久保存到 NgRx 存储中。然后模板获得该新值,并在随后的 onLazyLoad
中再次翻倍。
对我有用的解决方案是为此设置一个常量:
if (this.settings.features.VirtualScroll) {
pageSize = GridConfig.PageSize * 2;
} else {
pageSize = event.rows ? event.rows : 10;
}