angular - 将现有的 ng-container 树适配为虚拟树
问题描述
我有一个非常非常裸露的最小树,有时需要渲染成千上万的元素。这会导致一些非常糟糕的性能,因此该网站变得相当滞后。相反,我选择尝试cdk-virtual-scroll-viewport
,但我无法让它工作,因为我正在使用ngTemplateOutlet
. 例子:
<ul>
<ng-template #recursiveList let-root>
<li *ngFor="let item of root; trackBy:item?.id">
<!-- Show the actual elements, including + and - to expand/contract the tree -->
<ul [ngClass]="item?.expanded ? '' : 'hide'" *ngIf="item?.children && item?.children.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item?.children }"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: root }"></ng-container>
</ul>
我的root
数组看起来有点像这样:
[{
id: "aec04ef4-fc6a-481f-a12d-0ce987d494b3",
expanded: true,
children: [{
id: "cbf9e862-e932-410f-ad84-ed0a5ec1917a",
expanded: false,
children: []
}]
}]
我试着简单地这样做:
<ul>
<ng-template #recursiveList let-root>
<li *cdkVirtualFor="let item of root; trackBy:item?.id">
<!-- Show the actual elements, including + and - to expand/contract the tree -->
<ul [ngClass]="item?.expanded ? '' : 'hide'" *ngIf="item?.children && item?.children.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item?.children }"></ng-container>
</ul>
</li>
</ng-template>
<cdk-virtual-scroll-viewport style="height: 750px" itemSize="50">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: root }"></ng-container>
</cdk-virtual-scroll-viewport>
</ul>
所以基本上添加了cdk-virtual-scroll-viewport
元素并使用cdkVirtualFor
而不是ngFor
,但我收到一条错误消息:
没有 CdkVirtualScrollViewport 的提供者
我猜这是一个错误,因为它尚未关闭:https ://github.com/angular/components/issues/15277
知道如何调整我现有的代码吗?我面临的最大问题是隐藏/取消隐藏部分,因为由于ng-container
某种原因它无法使用它。
解决方案
在尝试了各种 CDK 虚拟化方法并没有得到满意的结果后,我为此构建了一个自定义组件。
https://github.com/gjcampbell/ooffice/tree/master/projects/of-tree
我建议使用一个库(我的库具有我所知道的最好的性能),或者如果您宁愿坚持当前的路径,那么请执行以下操作:
- 在您的数据上,存储层次结构信息,例如每个项目的深度和父项
- 递归遍历数据并从分层数据创建平面列表
- 呈现没有递归模板的平面列表。使用深度来确定压痕。仅传递给
cdkVirtualFor
其父项为 null 或展开的项。
推荐阅读
- python - 想要反转我的字符串位置,特殊字符应该在那里
- jquery - jQuery悬停触发“鼠标离开”而不离开光标
- powerbi - 在 PowerBI 中将单列拆分为多行?
- regex - 正则表达式捕获组并使用 OR 语句
- c# - 从另一个动作调用动作时使用角色授权属性
- android - 在Android中的某个时间显示通知的最佳方式是什么?
- java - java.sql.SQLDataException: ORA-01843: mes no válido on select query
- java - 如何将 Camunda 业务错误抛出?
- javascript - 表单提交后删除下拉选择
- hyperledger-fabric - 超级账本浏览器 | 开始.sh | ssl_transport_security | SSL3_GET_RECORD