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

Angular cdk-virtual-scroll-viewport初始化高度异常,resize后才正常

问题描述

使用Angular CDK虚拟滚动容器承载列表项,功能正常但初始化时仅占用约30%可用空间,调整屏幕尺寸(如放大开发者工具)后容器才会占满可用空间。

页面状态

  • 初始加载状态:[对应初始加载截图]
  • 调整尺寸后状态:[对应调整后截图]

相关代码

模板代码

<cdk-virtual-scroll-viewport class="Viewport" itemSize="50">
  <div *cdkVirtualFor="let item of threadsDetails$ | async" class="Item">
    {{ item.thread.id }}
  </div>
</cdk-virtual-scroll-viewport>

SCSS代码

.Viewport {
  height: 100%;
}

.Item {
  border-bottom: solid 1px black;
  height: 50px;
}

排查发现

通过Angular Chrome工具观察到,页面resize时会触发ngDoCheck。

已尝试方案

  • 订阅列表数据源并调用markForCheck
  • 调用cdk-virtual-scroll-viewport的ViewChild的ngOnInit(虽生效但会先显示30%高度再恢复,体验不佳)

解决方案

1. 手动触发虚拟滚动容器尺寸计算

在组件视图初始化完成后,直接调用虚拟滚动视图的checkViewportSize()方法,强制重新计算容器可用空间,解决初始高度异常问题:

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';

@Component({
  // 组件元数据
})
export class YourComponent implements AfterViewInit {
  @ViewChild(CdkVirtualScrollViewport) viewport!: CdkVirtualScrollViewport;
  threadsDetails$ = // 你的数据源Observable

  ngAfterViewInit(): void {
    // 加微延迟确保视图完全渲染
    setTimeout(() => {
      this.viewport?.checkViewportSize();
    }, 0);
  }
}

2. 确保父容器高度正确传递

height: 100%的生效依赖父元素已设置明确高度,检查所有上层容器样式,确保高度传递正常:

/* 示例:父容器设置占满视口高度 */
.parent-container {
  height: 100vh;
}

3. 结合异步数据源触发尺寸检查

如果列表数据是异步加载的,在数据就绪后触发尺寸检查,确保容器在数据加载完成后适配空间:

ngAfterViewInit(): void {
  this.threadsDetails$.subscribe(() => {
    setTimeout(() => {
      this.viewport?.checkViewportSize();
    }, 0);
  });
}

4. 启用自动尺寸适配(可选)

给虚拟滚动容器添加autoSize属性,让容器自动监听内容变化调整尺寸,适合数据量不大的场景:

<cdk-virtual-scroll-viewport class="Viewport" itemSize="50" [autoSize]="true">
  <!-- 列表项 -->
</cdk-virtual-scroll-viewport>

内容的提问来源于stack exchange,提问作者Aaron Nebbs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:27:20