【问题标题】:PrimeNG TurboTable - strange virtual scroll behaviour - keeps doubling event.rowsPrimeNG TurboTable - 奇怪的虚拟滚动行为 - 不断加倍 event.rows
【发布时间】:2019-08-31 15:38:52
【问题描述】:

我已经实现了一个使用 PrimeNG TurboTable 和 NgRx 的自定义 Grid 组件,并使用内置的 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

所以有2个问题:

  1. event.first 始终为 0
  2. 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"
    >

任何帮助或想法将不胜感激!谢谢!

【问题讨论】:

    标签: angular primeng ngrx primeng-turbotable


    【解决方案1】:

    之所以出现问题,是因为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;
    }
    

    【讨论】:

    • 我没有使用 NgRx 商店,但我仍然有同样的问题。 onLazyLoad() 方法在表的初始加载时被调用两次。你能帮帮我吗?
    【解决方案2】:

    这可能是因为在https://stackblitz.com/edit/github-primeng-virtualscroll-issue 中有一个硬编码的总记录计数参数到&lt;p-table&gt;。 在您的实际实现中,您可能设置为小于数据集大小或 0 (看起来您在那里有一个 observable。检查它的评估结果。尝试设置一些比您的数据集更大的数字以查看如果这个理论是正确的)

    检查[totalRecords]="(data$ | async)?.totalCount" 参数在您的&lt;p-table&gt; 实现中对您的评估。 希望这会解决它。

    【讨论】:

    • 感谢您的回复。不幸的是,这种情况并非如此。我尝试将 1000 硬编码为 totalRecords(大于我的数据集)并且行为是相同的。我认为分页设置在某处被保留并不断加倍,而不是仅仅从基本页面大小重新计算
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2015-11-17
    • 2018-10-28
    • 2018-09-15
    • 1970-01-01
    相关资源
    最近更新 更多