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

Angular mat-select结合optgroup时无法设置默认选中值问题

Angular Material 带分组多选mat-select默认值不选中修复方案

问题背景

需要将接口返回的默认数据设置为带mat-optgroup分组的多选mat-select表单选中项,直接调用setValue传入对应结构的数组后,选项始终无法正常选中。
相关代码片段如下:

  • 模板HTML代码:
<mat-form-field class="col-md-12 mt-top25">
  <mat-label>Department</mat-label>
  <mat-select formControlName="department" multiple (selectionChange)="getDepartment()" [compareWith]="compareWith">
    <mat-optgroup *ngFor="let group of departmentList" [label]="group.group" [disabled]="group.disabled">
      <mat-option *ngFor="let data of group.names" [value]="data">
        {{data.department}}
      </mat-option>
    </mat-optgroup>
  </mat-select>
</mat-form-field>
  • 下拉分组数据源结构:
[
  {
    "group": "Kuala Lumpur",
    "names": [
      {"id": 1, "department": "EMERGENCY ROOM", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur"},
      {"id": 2, "department": "FINANCE & ADMIN", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur"},
      {"id": 3, "department": "OUTPATIENT DEPARTMENT", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur"},
      {"id": 4, "department": "PHARMACY ", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur"},
      {"id": 5, "department": "MULTIDISCIPLINE 1", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur"}
    ]
  }
]
  • 预期默认选中值结构:
[
  {"department": "FINANCE & ADMIN", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur", "id": 2},
  {"department": "OUTPATIENT DEPARTMENT", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur", "id": 3}
]
  • 已尝试的操作:
this.f['department'].setValue([ 
  { "id": 2, "department": "FINANCE & ADMIN", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur" }, 
  { "id": 3, "department": "OUTPATIENT DEPARTMENT", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur" } 
]);

问题根因

mat-select默认采用对象引用相等的规则判断选项是否匹配,传入的默认值对象和下拉数据源里的选项对象不是同一个内存引用,就算字段值完全一致也会被判定为不匹配;同时如果compareWith函数未正确实现、或者赋值时机早于下拉数据源渲染完成,都会导致默认选中失效,该问题和mat-optgroup分组逻辑无关。

修复步骤

  1. 实现正确的compareWith比对函数
    用数据的唯一标识id做匹配判断,避免引用不一致、字段顺序/冗余字段导致的匹配失败,在组件TS类中添加如下公开方法:
    compareWith(option1: any, option2: any): boolean {
      // 空值边界处理
      if (!option1 || !option2) return false;
      // 唯一主键比对,稳定高效
      return option1.id === option2.id;
    }
    
  2. 调整赋值时序
    必须等departmentList下拉数据源加载完成、视图渲染结束后再调用setValue设置默认值,禁止在数据源未就绪时提前赋值,参考实现:
    // 拉取部门下拉分组数据
    this.loadDepartmentList().subscribe(res => {
      this.departmentList = res;
      // 等待视图更新完成后再赋值,避免找不到对应选项
      setTimeout(() => {
        this.f['department'].setValue([
          { "id": 2, "department": "FINANCE & ADMIN", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur" },
          { "id": 3, "department": "OUTPATIENT DEPARTMENT", "facilityCode": "KLAN", "facilityName": "Kuala Lumpur" }
        ]);
      }, 0);
    });
    

避坑提示

  • 不要对两个对象做全字段全等比对,只要字段顺序不一致、存在多余/缺失字段就会匹配失败,用唯一主键比对是最优方案
  • 确认模板中[compareWith]绑定的是组件类的公开方法,私有方法、模板内匿名函数都会导致绑定失效
  • 检查mat-option的[value]绑定的是完整部门对象,不要错绑为data.id等单个字段,否则会和传入的默认值结构不匹配

内容的提问来源于stack exchange,提问作者sandeep kumar chaurasia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:09:20