在 Angular Material 2 Table 中使用 Virtual Scroll with @angular/cdk-experimental
Using Virtual Scroll in Angular Material 2 Table with @angular/cdk-experimental
我有一个table显示这么多行,我想优化它的性能。我通过使用虚拟滚动技术找到了解决方案。这是 Angular Material CDK Vritual Scroll Viewport Component 的示例,我发现了一个简单的 div
:
<cdk-virtual-scroll-viewport class="list-container lg" [itemSize]="52.5">
<div *cdkVirtualFor="let state of statesObservable | async;" class="list-group-item">
<div class="state">{{state.name}}</div>
<div class="capital">{{state.capital}}</div>
</div>
</cdk-virtual-scroll-viewport>
但是,我想将它与 Angular Material Table 集成,如下所示
<table mat-table [dataSource]="dataSource">
<ng-container *ngFor="let c of displayedColumns" [matColumnDef]="c">
<th mat-header-cell *matHeaderCellDef>{{getTitle(c)}}</th>
<td mat-cell style="white-space: pre-wrap;" *matCellDef="let element"> {{element[c]}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
我想知道如何将 cdk-virtual-scroll-viewport
包装成 mat-table
。我的 table 最多显示 1000 行和 20 多列,并且在加载和滚动时性能非常慢。
PS:我知道可以用Paginator解决,但我不想那样做。
版本
"@angular/material": "^6.2.0"
@angular/cdk": "^6.2.0"
@angular/cdk-experimental": "^6.2.1"
"@angular/core": "6.0.3"
"@angular/cli": "6.0.7"
这不是当前开箱即用的东西。 CdkTable
(或MatTable
)组件不支持虚拟滚动YET.
内置于 @angular/cdk
中的虚拟滚动支持仍处于试验阶段 - 这将在版本 7 中改变。
但是,当此功能落地时,下一步将是为 table 实现它。我会解释为什么。
cdk-virtual-scroll-viewport
是 *cdkVirtualFor
指令的容器,如果我们查看这个指令 (CdkVirtualForOf
) 我们可以看到
考虑到这一点,让我们看一下 CdkTable
相似性并非偶然,table(经过一些调整)可以像 cdkVirtualFor
一样被 cdk-virtual-scroll-viewport
使用。
我不确定最终的实现是什么,开发人员是否能够从外部包装 table 或 table 将在内部设置它,但这是方向会的。
如果我不得不猜测,我会说开发者会选择是否要用虚拟卷轴包裹 table。这是因为 cdk-virtual-scroll-viewport
不查询 cdkVirtualFor
(通过 ViewChild
),它是被动的并等待附加它的东西。这表明这是事先想到的。
您现在可以通过扩展 CdkTable
并自己进行调整来完成,这将需要了解 table 的内部结构,并且可能需要一些时间。我建议稍等一下。
暂不支持。但是有些人已经尝试做一些 POC。这是一个 https://github.com/angular/material2/issues/10122#issuecomment-440442656 .
在此 issue 中还讨论了虚拟滚动以及上述 POC 的工作原理。
I made a custom directive,有什么办法可以解决这个问题:
1) 安装包:$ npm install -save ng-table-virtual-scroll
并将其添加到导入中:
import { TableVirtualScrollModule } from 'ng-table-virtual-scroll';
@NgModule({
imports: [
// ...
TableVirtualScrollModule
]
})
export class AppModule { }
2) 使用包中的自定义 DataSource
:
import { TableVirtualScrollDataSource } from 'ng-table-virtual-scroll';
@Component({...})
export class MyComponent {
dataSource = new TableVirtualScrollDataSource();
}
3) 在视口容器上使用指令:
<cdk-virtual-scroll-viewport tvsItemSize style="height: 400px;">
<table mat-table [dataSource]="dataSource">
...
</table>
</cdk-virtual-scroll-viewport>
该指令允许您使用 mat-table
的所有功能,例如排序、分页、粘性 header/column 等
我有一个table显示这么多行,我想优化它的性能。我通过使用虚拟滚动技术找到了解决方案。这是 Angular Material CDK Vritual Scroll Viewport Component 的示例,我发现了一个简单的 div
:
<cdk-virtual-scroll-viewport class="list-container lg" [itemSize]="52.5">
<div *cdkVirtualFor="let state of statesObservable | async;" class="list-group-item">
<div class="state">{{state.name}}</div>
<div class="capital">{{state.capital}}</div>
</div>
</cdk-virtual-scroll-viewport>
但是,我想将它与 Angular Material Table 集成,如下所示
<table mat-table [dataSource]="dataSource">
<ng-container *ngFor="let c of displayedColumns" [matColumnDef]="c">
<th mat-header-cell *matHeaderCellDef>{{getTitle(c)}}</th>
<td mat-cell style="white-space: pre-wrap;" *matCellDef="let element"> {{element[c]}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
我想知道如何将 cdk-virtual-scroll-viewport
包装成 mat-table
。我的 table 最多显示 1000 行和 20 多列,并且在加载和滚动时性能非常慢。
PS:我知道可以用Paginator解决,但我不想那样做。
版本
"@angular/material": "^6.2.0"
@angular/cdk": "^6.2.0"
@angular/cdk-experimental": "^6.2.1"
"@angular/core": "6.0.3"
"@angular/cli": "6.0.7"
这不是当前开箱即用的东西。 CdkTable
(或MatTable
)组件不支持虚拟滚动YET.
内置于 @angular/cdk
中的虚拟滚动支持仍处于试验阶段 - 这将在版本 7 中改变。
但是,当此功能落地时,下一步将是为 table 实现它。我会解释为什么。
cdk-virtual-scroll-viewport
是 *cdkVirtualFor
指令的容器,如果我们查看这个指令 (CdkVirtualForOf
) 我们可以看到
考虑到这一点,让我们看一下 CdkTable
相似性并非偶然,table(经过一些调整)可以像 cdkVirtualFor
一样被 cdk-virtual-scroll-viewport
使用。
我不确定最终的实现是什么,开发人员是否能够从外部包装 table 或 table 将在内部设置它,但这是方向会的。
如果我不得不猜测,我会说开发者会选择是否要用虚拟卷轴包裹 table。这是因为 cdk-virtual-scroll-viewport
不查询 cdkVirtualFor
(通过 ViewChild
),它是被动的并等待附加它的东西。这表明这是事先想到的。
您现在可以通过扩展 CdkTable
并自己进行调整来完成,这将需要了解 table 的内部结构,并且可能需要一些时间。我建议稍等一下。
暂不支持。但是有些人已经尝试做一些 POC。这是一个 https://github.com/angular/material2/issues/10122#issuecomment-440442656 .
在此 issue 中还讨论了虚拟滚动以及上述 POC 的工作原理。
I made a custom directive,有什么办法可以解决这个问题:
1) 安装包:$ npm install -save ng-table-virtual-scroll
并将其添加到导入中:
import { TableVirtualScrollModule } from 'ng-table-virtual-scroll';
@NgModule({
imports: [
// ...
TableVirtualScrollModule
]
})
export class AppModule { }
2) 使用包中的自定义 DataSource
:
import { TableVirtualScrollDataSource } from 'ng-table-virtual-scroll';
@Component({...})
export class MyComponent {
dataSource = new TableVirtualScrollDataSource();
}
3) 在视口容器上使用指令:
<cdk-virtual-scroll-viewport tvsItemSize style="height: 400px;">
<table mat-table [dataSource]="dataSource">
...
</table>
</cdk-virtual-scroll-viewport>
该指令允许您使用 mat-table
的所有功能,例如排序、分页、粘性 header/column 等