单个Form Control可否绑定多个值或完整对象?Angular mat-select场景问询
问题解答
核心结论
FormControl完全支持存储整个对象,你当前写的<mat-option [value]="item"的写法本身就是正确的,完全可以通过属性调用拿到对应字段。
取值方式
你可以直接按如下方式获取对应字段:
- 如果
serviceNumber是单独声明的FormControl:// 取整个选中对象 const selectedArea = this.serviceNumber.value; // 单独取number const selectedNumber = selectedArea?.number; // 单独取name const selectedName = selectedArea?.name; - 如果
serviceNumber是嵌套在FormGroup下的字段:const selectedArea = this.你的FormGroup实例.get('serviceNumber')?.value; const selectedNumber = selectedArea?.number; const selectedName = selectedArea?.name;
注意事项(必填,否则会出现回填不显示选中项的问题)
当mat-select的选项值为对象类型时,Angular默认通过对象引用判断是否选中,如果你需要给表单回填默认值、或者异步加载选项后匹配已存值,会出现值对得上但下拉框不显示选中项的问题,需要额外添加compareWith比较函数:
- 模板中给mat-select添加配置:
<mat-select [formControl]="serviceNumber" (selectionChange)="selectionChanged()" [compareWith]="compareServiceArea" <!-- 新增这行 --> > - 组件ts中添加比较函数,用业务唯一标识(这里是number)做比较即可:
compareServiceArea(area1: ServiceArea, area2: ServiceArea): boolean { // ServiceArea是你item的类型,没有声明类型可以写any return area1 && area2 ? area1.number === area2.number : area1 === area2; }
可选替代方案(不想存对象时用)
如果你确实不想把整个对象存在FormControl里,也可以拆分两个FormControl分别存number和name,在选择变更时手动赋值:
- 先声明两个FormControl:
serviceNumber = new FormControl(''); serviceName = new FormControl(''); - 模板中option的value绑定回number:
<mat-option *ngFor="let item of items.serviceAreas" [value]="item.number"> {{item.number}} {{item.name}} </mat-option> - selectionChange事件中匹配选中项给两个字段赋值:
selectionChanged(event: MatSelectChange) { const selected = this.items.serviceAreas.find(item => item.number === event.value); if (selected) { this.serviceNumber.setValue(selected.number); this.serviceName.setValue(selected.name); } }
这种方式需要额外做一次数组查询,不如直接存对象便捷,仅适合有特殊表单结构要求的场景使用。
内容的提问来源于stack exchange,提问作者lank81
相关产品推荐
相关产品推荐

