You need to enable JavaScript to run this app. mat-select-trigger结合cdk-virtual-scroll-viewport不生效问题求助
优惠活动
大模型
产品
解决方案
定价
更多

mat-select-trigger结合cdk-virtual-scroll-viewport不生效问题求助

修复方案

问题根因

  1. mat-select未绑定选中值,且虚拟滚动初始化时不在视口内的mat-option不会渲染,mat-select无法匹配到对应选项导致初始值不显示
  2. 未配置cdkVirtualFor的trackBy函数,窗口resize触发虚拟滚动重渲染时,已选中的option节点被销毁重建导致选中态丢失
  3. 虚拟滚动视口未固定高度/滚动触发时机过早,导致选中项滚动定位失效

具体修改步骤

1. 模板修改

  • 给mat-select添加[value]绑定,同步选中值
  • 给*cdkVirtualFor添加trackBy配置,复用DOM节点
  • 建议将选中变更事件绑定到mat-select而非每个mat-option,减少不必要的事件监听

修改后模板代码:

<mat-select 
  [value]="selected"
  (openedChange)="openChange($event)"
  (selectionChange)="onSelectionChange($event)"
>
  <mat-select-trigger>
    <img src="assets/{{selected[1]}}.svg" alt=""/>
    + {{selected[0]}}
  </mat-select-trigger>
  <cdk-virtual-scroll-viewport itemSize="48" class="viewport">
    <mat-option 
      *cdkVirtualFor="let i of items; templateCacheSize: 20; trackBy: trackByItem"
      [value]="i"
    >
      <img src="assets/{{ i[1] }}.svg" alt=""/>
      + {{i[0]}}
    </mat-option>
  </cdk-virtual-scroll-viewport>
</mat-select>

对应样式补充(必须给虚拟滚动视口设置固定高度):

.viewport {
  height: 288px; /* 按最多展示6项计算 6*48px,可按需调整 */
  width: 100%;
}

2. TS代码修改

  • 新增trackByItem函数,按选项唯一标识复用节点
  • 调整openChange里的滚动触发时机,确保视口初始化完成后再滚动
  • 调整选中变更逻辑,直接从mat-select的事件拿值

修改后TS代码:

// 新增trackBy函数
trackByItem(index: number, item: any[]) {
  // 用选项的唯一标识(此处为svg文件名)作为追踪key
  return item[1];
}

openChange($event: boolean) {
  if ($event) {
    // 加0ms延时确保虚拟滚动视口已完成初始化
    setTimeout(() => {
      const selectedIndex = this.items.findIndex(elem => elem[1] === this.selected[1]);
      if (selectedIndex > -1) {
        this.cdkVirtualScrollViewPort.scrollToIndex(selectedIndex);
        this.cdkVirtualScrollViewPort.checkViewportSize();
      }
    }, 0);
  } 
}

// 调整选中变更事件逻辑
onSelectionChange(event: MatSelectChange) {
  this.selected = event.value;
}

3. 窗口resize异常修复

如果调整窗口大小后仍有选中值丢失问题,可新增窗口resize监听,主动触发虚拟滚动视口尺寸校验:

@HostListener('window:resize')
onWindowResize() {
  if (this.cdkVirtualScrollViewPort) {
    this.cdkVirtualScrollViewPort.checkViewportSize();
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 11:54:04