I've implemented a custom Grid component that uses PrimeNG TurboTable and NgRx and I've added the virtual scroll feature to it using the built-in TurboTable virtual scroll. It is also lazy loading, with onLazyLoad
handler. However, I get this strange behaviour when onLazyLoad
is called as I am scrolling through the grid results.
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
So there are 2 problems:
event.first
always stays 0event.rows
keeps doubling to very high values
I thought that it's a bug in PrimeNG but when I've tried to reproduce it with a simple StackBlitz, there it is behaving correctly. https://stackblitz.com/edit/github-primeng-virtualscroll-issue
I see this on 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
So event.rows
stays constant as it is supposed to and event.first
increases normally.
Looks like something is triggering this from the way I use the TurboTable, but I don't know what. What could be the issue? Here is the relevant code from my grid component:
The lazy load handler:
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)
);
}
}
The parameters I pass in the template:
<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"
>
Any help or ideas would be much appreciated! Thanks!