角材料数据表加载缓慢

问题描述 投票:0回答:2

我在棱角分明的“材质应用程序”中遇到了一些麻烦。我正在使用带有分页器的数据表。数据不必排序。

在加载数据时,我正在显示垫旋转器

<div *ngIf="schools !== undefined">
        <mat-spinner *ngIf="showSpinner" style="margin:0 auto;"></mat-spinner>
        <div *ngIf="!showSpinner">
            Keine Daten gefunden.
        </div>
</div>
<div *ngIf="schools !== undefined">
   <mat-table [dataSource]="dataSource"> 
      ...
   </mat-table>
   <mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" [pageSize]="20" showFirstLastButtons></mat-paginator>
</div>

在正常情况下,我正在加载数据,并且在加载数据然后显示数据时,旋转器停止旋转。效果很好。

但是对于一个有大约400行的表,我遇到了这个问题:

成功加载数据后,微调器会变得非常非常慢,持续大约一秒钟,并且数据表将显示所有内容。 (由分页者分隔)

[从api加载数据大约需要400毫秒,而解析它大约需要3毫秒,所以不应该成为问题。

我正在这样加载数据:

ngOnInit() {
    setTimeout(() => {
      this.showSpinner = false;
    }, 5000);

    this.userID = this.authService.getCurrentUser.uid;
    this.loadData();
}

loadData() {
    this.apiService.getSchools().subscribe((schoolsData: any) => {
      this.schools = this.refParser.parse(schoolsData);
      this.dataSource = new MatTableDataSource(this.schools);

      this.cdr.detectChanges();
      this.dataSource.paginator = this.paginator;
    });
}

我已经找到关于stackoverflow的帖子,该帖子对我有帮助(Angular 6 MatTable Performance in 1000 rows.)。但这并没有帮助我:(

我这样尝试过:

ngOnInit() {
    setTimeout(() => {
      this.showSpinner = false;
    }, 5000);

    this.userID = this.authService.getCurrentUser.uid;
    //this.loadData();
    this.dataSource = new MatTableDataSource();

    this.dataSource.paginator = this.paginator;
}

ngAfterViewInit(){
    setTimeout(() => {
      this.apiService.getSchools().subscribe((schoolsData: any) => {
        this.schools = this.refParser.parse(schoolsData);
        this.dataSource.data = this.schools;
        this.cdr.detectChanges();
      })
    })
}

它并没有给我带来任何性能提升。唯一发生的是,分页器不再工作。

有人知道什么可以帮助我改善应用程序的性能吗?

感谢您的回答:)

angular performance datatable material
2个回答
0
投票

完成加载数据后,您应该禁用微调器:

loadData() {
    this.apiService.getSchools().subscribe((schoolsData: any) => {
      this.schools = this.refParser.parse(schoolsData);
      this.dataSource = new MatTableDataSource(this.schools);
      this.showSpinner = false; // here!

      this.cdr.detectChanges();
      this.dataSource.paginator = this.paginator;
    });

并且可能会像这样更改您的模板:

<mat-spinner *ngIf="showSpinner" style="margin:0 auto;"></mat-spinner>
<div *ngIf="!shools && !showSpinner">
    Keine Daten gefunden.
</div>

<div *ngIf="dataSource">
   <mat-table [dataSource]="dataSource"> 
      ...
   </mat-table>
   <mat-paginator [pageSizeOptions]="[10, 20, 50, 100]" [pageSize]="20" showFirstLastButtons></mat-paginator>
</div>

0
投票

我过去也遇到过同样的问题,Mat-Table本身会处理变更检测,因此不必考虑Mat表格,数据源设置错误。

如果一次性传递所有数据,它将仅在第一次加载时呈现整个数据,并显示滞后。

由于使用分页器,因此应将数据源分成pageSize,以便在加载时仅呈现20个元素。

创建一个新的分页器实例:actualPaginator: MatPaginator;

@ViewChild(MatPaginator, {static: false})
  set paginator(value: MatPaginator) {
    this.actualPaginator = value;
  }

this.actualPaginator.pageIndex = Math.ceil(this.schools.length/this.actualPaginator.pageSize) - 1;

 let nextPageData: any[] = [];
 nextPageData = this.schools.slice((this.actualPaginator.pageSize * this.actualPaginator.pageIndex),(this.actualPaginator.pageSize * (this.actualPaginator.pageIndex + 1)));
 this.dataSource.data = nextPageData;

因此分发您的this.schools数据并按页面大小计数加载它,单击下一步按钮更改this.schools数据的下一个插槽的数据源将解决您的问题。

您必须通过创建新的MatPaginator实例作为关键解决方案来分别操作mat-paginator。

© www.soinside.com 2019 - 2024. All rights reserved.