Angular Material Virtual Scroll高度调整异常问题求助
问题根源
当 Virtual Scroll 组件在未显示的 Sidenav 中初始化时,由于容器处于不可见状态,组件无法正确计算视口的实际尺寸,导致虚拟滚动的布局逻辑错误,表现为条目集中在顶部且仅显示少量内容。窗口 resize 时会触发 Angular 的布局检测,间接修正了视口尺寸计算,因此显示恢复正常。
修复步骤
1. 引用组件实例
在组件类中通过 ViewChild 获取 Sidenav 和 Virtual Scroll 视口的实例:
import { Component, ViewChild } from '@angular/core'; import { MatSidenav } from '@angular/material/sidenav'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { @ViewChild(MatSidenav) sidenav!: MatSidenav; @ViewChild(CdkVirtualScrollViewport) viewport!: CdkVirtualScrollViewport; items = Array.from({length: 10000}).map((_, i) => `Item #${i}`); onSidenavOpened() { // 延迟执行确保 Sidenav DOM 渲染完成,视口尺寸已更新 setTimeout(() => { this.viewport.checkViewportSize(); // 可选:滚动到顶部保证初始显示位置正确 this.viewport.scrollToIndex(0); }, 0); } }
2. 绑定 Sidenav 打开事件
在模板中为 Sidenav 添加 openedChange 事件绑定,触发视口尺寸重新计算:
<mat-sidenav #sidenav (openedChange)="onSidenavOpened()"> <cdk-virtual-scroll-viewport itemSize="50" class="example-viewport"> <div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div> </cdk-virtual-scroll-viewport> </mat-sidenav>
原理说明
setTimeout 确保 Sidenav 完全展开并完成 DOM 渲染后,再调用 checkViewportSize() 让 Virtual Scroll 重新计算视口的高度和可见区域,修正虚拟滚动的布局逻辑。这一操作替代了窗口 resize 时的自动检测,直接触发正确的尺寸计算。
内容的提问来源于stack exchange,提问作者Mad Eddie
相关产品推荐
相关产品推荐

