PrimeNG 使用异步管道延迟加载数据

PrimeNG Lazy load data with async pipe

我需要在 PrimeNG 数据中显示大量数据(400.000 条记录)table。为此,我需要延迟加载 table,因为您无法一次将所有数据加载到 table(这会使您的浏览器崩溃)。

为了创建 table 我使用了以下技术:


我想要什么

我正在尝试创建延迟加载 table,如 PrimeNG docs 所示,其中数据从服务器加载并显示在 table 中。当用户导航到下一个选项卡时,将加载并显示下一个 x 量的数据。

唯一的区别是我在将所有数据提供给 table 组件之前从服务器获取所有数据。这样我只需要从数据源中选择某些数据并将其显示给用户。


问题

在尝试实现它时,我 运行 遇到了 (onLazyLoad) 函数仅调用一次的问题,在 onInit() 阶段,在从服务器加载数据之前。

我可以通过添加 [lazyLoadOnInit]="false" 来撤消此操作,但这会导致延迟加载函数根本不会被调用。我希望我可以通过在加载数据时更改 [totalRecords] 属性 来触发加载功能,但这也不会触发该功能。

我在 PrimeNG p-table code 中找不到可用于触发 (onLazyLoad) 的任何其他函数,还是我遗漏了什么?


代码

public ngOnInit(): void {
  this.cars$ = this.carService.entities$; // = []
  this.carService.getAll(); // = [Car, Car, Car, Car] OR []
}

this.carService.entities$ 的默认值为 [] 并填充了 getAll() 函数的结果(如果没有结果,也可以是 []


我在 a StackBlitz 中重现了我的问题。在这里您可以看到数据从未显示,因为 (onLazyLoad) 仅在第一次调用时被调用,当时数据为空。

请注意,我使用 Angular Async pipe 将数据传递到我的组件中。这意味着我需要检查 ngOnChanges() 函数中的更改。

像这样更新 app.template

<ng-container *ngIf="cars$ | async as data">
  <table-component [data]="data"></table-component>
</ng-container>

似乎 p-table lasyload 不会在数据更改时触发,即使数据 属性 从 undefined 更改为 object(arry)

stackblitz

已更新

没有异步管道 获取数据

  public ngOnInit(): void {
    this.carService.getAll().subscribe(data => this.data = data);
  }

ngOnChanges 方法

  public ngOnChanges(change: SimpleChanges): void {
    if(change.data) {
      if (change.data.currentValue) {
      this.datasource = change.data.currentValue;
      this.totalRecords = Array.isArray(change.data.currentValue) ? change.data.currentValue.length : 0;
      this.cars = this.datasource.slice(0, 10); // row number
      this.loading = false;
      }
    }
  }

check this article explains how to use async pipe and change detection

stackblitz

感谢 malbarmawi 我设法用新记录更新了 table。唯一仍然存在的问题是延迟加载只触发了 table 的 onInit()。这为时过早,因为数据尚未加载。

所以我需要找到一种触发延迟加载的方法。我注意到 table 的方法是 public,所以我可以将 table 作为 @ViewChild 注入并自己触发延迟加载。

/**
 * A reference to the primeng table. Since all of it's methods are public we can
 * directly access the methods we need to trigger lazy loading correctly.
 */
@ViewChild(Table)
private tableRef: Table;

public ngOnChanges(change: SimpleChanges): void {
   if(change.data && change.data.currentValue) {
     this.datasource = change.data.currentValue;
     this.totalRecords = Array.isArray(change.data.currentValue) ? change.data.currentValue.length : 0;

     // Trigger lazy loading
     this.tableRef.onPageChange({ first: 0, rows: this.rows });
   }
}

因为我现在有延迟加载,所以我还可以实现一个虚拟滚动条来提高 table 的性能,并且可以处理我的 400.000 条记录。

为此,我只需要将 tables 属性更新为(注意虚拟属性):

<p-table [columns]="cols" [value]="cars" [scrollable]="true" [rows]="rows" [scrollHeight]="scrollHeight" [virtualRowHeight]="rowHeight" [virtualScroll]="true" [lazy]="true" (onLazyLoad)="loadCarsLazy($event)"  [totalRecords]="totalRecords" [loading]="isLoading"></p-table>

可以找到此代码的完整示例 on stackblitz