You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material Virtual Scroll高度调整异常问题求助

解决方案:Angular Material Sidenav 中 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:39:18