PrimeNG带有异步管道的延迟加载数据

时间:2019-03-15 13:39:45

标签: angular typescript lazy-loading primeng primeng-datatable

我需要在PrimeNG数据表中显示大量数据(400.000条记录)。为此,我需要一个惰性加载表,因为您不能一次将所有数据加载到表中(这会使浏览器崩溃)。

为了创建表格,我正在使用以下技术:


我想要什么

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

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


问题

在尝试实现它时,我遇到一个问题,即在从服务器加载数据之前,在(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()函数中的更改。

2 个答案:

答案 0 :(得分:1)

只需像这样更新app.template

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

即使数据属性从undefined更改为object(arry),看来p表lasyload都不会在数据更改时触发

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

答案 1 :(得分:0)

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

所以我需要找到一种触发延迟加载的方法。我注意到表的方法是公共的,因此我可以将表作为@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 });
   }
}

由于我现在有延迟加载,所以我还可以实现一个虚拟滚动条来改善表的性能,并使其可以处理400.000条记录。

为此,我只需要将表属性更新为(请注意virtual-properties):

<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