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

CDK Virtual Scroll多选下拉框选中状态丢失问题求助

解决Angular Material多选下拉虚拟滚动选中状态丢失问题

核心原因

虚拟滚动会销毁不在视口内的mat-option组件,当这些组件被重新渲染时,默认不会自动恢复选中状态——因为mat-select的选中值绑定没有和虚拟滚动的选项做精准关联。

具体解决步骤

1. 绑定唯一标识而非整个对象

多选模式下,mat-select的[(value)]或[(ngModel)]优先绑定选项的唯一标识(比如id),避免因对象引用变化导致的识别失败:

<mat-select [(value)]="selectedIds" multiple>
  <cdk-virtual-scroll-viewport itemSize="48" class="virtual-scroll-list">
    <mat-option *cdkVirtualFor="let opt of options" [value]="opt.id">
      {{ opt.label }}
    </mat-option>
  </cdk-virtual-scroll-viewport>
</mat-select>
selectedIds: number[] = [];
options: {id: number, label: string}[] = [...]; // 1500+条数据

2. 手动指定选中状态(对象绑定场景)

如果必须绑定整个对象,要给mat-option加上[selected]属性,通过唯一标识判断选中状态,同时搭配trackBy优化渲染:

<mat-select [(value)]="selectedItems" multiple>
  <cdk-virtual-scroll-viewport itemSize="48" class="virtual-scroll-list">
    <mat-option 
      *cdkVirtualFor="let opt of options; trackBy: trackById"
      [value]="opt"
      [selected]="selectedItems.some(item => item.id === opt.id)">
      {{ opt.label }}
    </mat-option>
  </cdk-virtual-scroll-viewport>
</mat-select>
selectedItems: {id: number, label: string}[] = [];
trackById(index: number, item: any): number {
  return item.id;
}

3. 关闭虚拟滚动缓存(可选兜底)

如果前两种方法无效,可以尝试禁用虚拟滚动的缓存,确保组件重新渲染时能正确读取选中状态:

<cdk-virtual-scroll-viewport itemSize="48" class="virtual-scroll-list" [cacheSize]="0">
  <!-- mat-option 内容 -->
</cdk-virtual-scroll-viewport>

注意:此方法可能轻微影响滚动流畅度,优先用前两种方案。

4. 监听选中事件强制同步状态

监听mat-select的selectionChange事件,手动同步选中数组,避免状态不一致:

<mat-select [(value)]="selectedIds" multiple (selectionChange)="syncSelection($event)">
  <!-- 虚拟滚动内容 -->
</mat-select>
syncSelection(event: MatSelectChange) {
  this.selectedIds = [...event.value];
}

内容的提问来源于stack exchange,提问作者Pratik Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:52:14