Angular 14中mat-select默认值不生效问题(从Angular 13升级后)
我之前处理过类似Angular版本升级后mat-select默认值不显示的问题,结合你的代码来看,大概率是Angular 14对表单控件的变更检测、DOM重建逻辑或者MatSelect的绑定规则做了更严格的调整。下面是几个针对性的解决方案,你可以逐一尝试:
1. 确认值的类型与完全匹配
首先要排查最基础的问题:表单控件的初始值和mat-option的value是否完全一致(包括字符串大小写、空格、特殊字符等)。Angular 14在值匹配上的校验比13更严格,哪怕细微的差异都会导致默认值无法选中。
你可以在formStartup方法里添加日志,对比初始值和可选值:
formStartup(datasource: any[]) { // ... 原有代码 this.basketLayerData.forEach(element => { console.log("初始materialName:", element.material.materialName); console.log("可选materialName列表:", this.basketInfoService.allScrapMaterials.map(m => m.materialName)); formArrayControl.push(this.fb.group({ materialName: [element.material.materialName, Validators.required], // ... 其他控件 })) }); // ... 原有代码 }
如果发现值不一致,需要先统一数据源的格式。
2. 切换DOM时避免*ngIf导致的绑定断裂
你的代码中,input和mat-select通过*ngIf="editFlag"切换显示——*ngIf会销毁旧DOM并重建新元素,Angular 14可能在这个过程中没有正确同步表单控件的值到新创建的mat-select上。
建议改用[hidden]替代*ngIf,这样DOM元素会被保留,绑定关系不会中断:
<mat-form-field *ngIf="column.header == 'Material Name'" appearance="outline"> <!-- 用[hidden]替代*ngIf --> <input [hidden]="editFlag" type="text" style="color: #1a3d78; font-weight: normal; width: 98%;" matInput [formControlName]="column.field"> <mat-select [hidden]="!editFlag" [formControlName]="column.field"> <mat-option *ngFor="let ScrapMaterial of basketInfoService.allScrapMaterials let i=index" [value]="ScrapMaterial.materialName" (click)="onSelect(formIndex,ScrapMaterial.idMaterial)"> {{ScrapMaterial.materialName}} </mat-option> </mat-select> </mat-form-field>
3. 启用表单后手动触发控件状态更新
从禁用状态切换到启用状态时,Angular 14可能没有自动触发控件的变更检测。你可以在onEditClicked方法中,启用表单数组后手动更新每个控件的状态:
首先注入ChangeDetectorRef到组件中:
import { ChangeDetectorRef } from '@angular/core'; constructor( // ... 其他依赖 private cdr: ChangeDetectorRef ) {}
然后修改onEditClicked方法:
onEditClicked() { if (!this.editFlag) { this.editFlag = true; this.basketInfoService.editFlag.next(true); let formArrayControl = <UntypedFormArray>this.basketFormGroup.get("formArray"); formArrayControl.enable(); // 手动更新每个materialName控件的状态,触发变更检测 formArrayControl.controls.forEach(control => { control.get('materialName')?.updateValueAndValidity({ emitEvent: false }); }); this.cdr.detectChanges(); } else { console.log("edit is already enabled!") } }
updateValueAndValidity会强制控件同步值并更新状态,detectChanges则触发组件的变更检测,确保视图刷新。
4. 检查Angular Material版本兼容性
确保你的@angular/material版本和Angular核心版本完全匹配(都是14.x.x)。版本不兼容也可能导致组件行为异常,可以通过以下命令查看和升级:
# 查看当前版本 npm list @angular/material @angular/core # 升级到对应版本(如果不一致) npm install @angular/material@14.x.x @angular/cdk@14.x.x --save
备注:内容来源于stack exchange,提问作者mojde jalali

