angular - Angular Material Datatable 加载缓慢
问题描述
我的角度材料应用程序遇到了一些麻烦。我正在使用带有分页器的数据表。数据不必排序。
在加载数据时,我正在展示一个垫子旋转器
<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();
})
})
}
它没有给我任何性能提升。唯一发生的事情是,分页器不再工作了。
有谁知道什么可以帮助我提高我的应用程序的性能?
谢谢您的回答:)
解决方案
我过去也遇到过同样的问题,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。
推荐阅读
- python - 我如何让scrapy在段落周围没有css标签的旧网页上查找和获取特定单词
- reactjs - 我如何从 http 重定向到 https express.js
- deep-learning - 在这种情况下,简单 GAN 是否与条件 GAN 一样工作
- php - 如何建立非安全连接
- python - 在 Flask SQLAlchemy 中修改 Sqlite 数据库结构
- jenkins - 停止后如何在特定端口上启动 Jenkins?
- spring - 如果我尝试使用 lombok 获取布尔 @Transient 变量的值,为什么会出错?
- c# - 将视图拖到其他视图下时出现 WPF 性能问题
- c - 为什么“指向不同数组的指针数组”的符号与传统二维数组的符号相匹配?
- angular - 为什么 ng 命令仅在 Vs 代码和命令提示符下以“管理员身份”工作