如何让CDK Virtual Scroll在表格列恢复后正常渲染列表项
CDK Virtual Scroll 表格全列移除后恢复时数据行不渲染问题修复
问题场景
对接API返回列表数据的表格集成CDK Virtual Scroll,支持单独移除、恢复表格列及对应数据项。异常表现:移除全部表格列后触发恢复操作,表格列头可正常展示,对应的数据行无法渲染。
根因说明
- 当
displayedColumns变为空数组时,CDK虚拟滚动视口会将可渲染内容高度判定为0,清空已缓存的行视图引用 - 常规列显隐逻辑仅更新
displayedColumns变量,未触发表格行重渲染和虚拟滚动视口的尺寸重算,恢复列后视口仍保留之前高度为0的判定结果,不会拉取可视范围的数据渲染行 - 若实现列显隐时用
*ngIf直接销毁列定义节点,列恢复时模板初始化时序晚于虚拟滚动的渲染检查,也会导致数据行不展示
修复步骤
- 模板中给虚拟滚动容器和表格标记引用变量,组件内获取对应实例
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import { CdkTable } from '@angular/cdk/table'; @ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport; @ViewChild(CdkTable) table: CdkTable;
- 调整列恢复逻辑,更新列配置后强制触发重绘
restoreAllColumns() { // 原有业务逻辑:重置显示列为全量列 this.displayedColumns = this.allColumnKeys; // 新增重绘逻辑 this.table.renderRows(); // 等视图更新完成后重算视口尺寸 setTimeout(() => { this.viewport.checkViewportSize(); // 兜底:触发滚动事件强制刷新可视区渲染 const offset = this.viewport.measureScrollOffset(); this.viewport.scrollToOffset(offset); }); }
- 调整列显隐实现方式:不要用
*ngIf直接销毁<ng-container cdkColumnDef>节点,仅通过displayedColumns控制列是否展示,避免列定义模板销毁、重建的时序问题。
避坑提示:列全部移除时不要同步将虚拟滚动绑定的数据源设为空,仅控制列显隐即可;如果业务需要清空数据源,要等数据源赋值完成后再执行上述重绘逻辑。
内容的提问来源于stack exchange,提问作者user14160660
相关产品推荐
相关产品推荐

