如何重置mat-option选中值?Angular表单取消编辑区域未重置问题
问题描述
我有一个表单,编辑时可通过mat-select选择区域,同时编辑其他输入字段。点击取消按钮后,输入字段能按预期重置回原值,但选择的区域却保持修改后的值,无法恢复(比如原本是DE,修改后取消,期望回到DE,但实际还是修改后的选项)。
相关代码片段
区域选择的mat-select组件
<mat-select [(ngModel)]="editedMarket.region" [placeholder]="selectedRegion"> <mat-option [value]="null"> none </mat-option> <mat-option *ngFor="let region of marketRegions" [value]="region"> {{ region }} </mat-option> </mat-select>
editedMarket.region为字符串类型。
编辑按钮触发逻辑
点击编辑按钮时调用:
onEditButtonClick(entity: T) { this.resetEditedEntity(); this.entityOnEdit = entity; this.columns.forEach(editableColumn => { this.editEntityForm.get(editableColumn.name).setValue(entity[editableColumn.name]); }); this.startEditingEntity.emit(entity); Object.values(this.editEntityForm.controls).forEach(control => control.updateValueAndValidity()); }
该方法会触发:
onStartEditingMarket(market: Market): void { this.editedMarket = market; }
取消按钮触发逻辑
取消按钮代码:
<button mat-icon-button (click)="onCancelButtonClick()"> <mat-icon>close</mat-icon> </button>
对应的处理函数:
onCancelButtonClick() { this.resetEditedEntity(); this.cancelEditingEntity.emit(); }
该方法会触发:
onCancelEditingMarket(): void { this.editedMarket = undefined; }
曾尝试调用表单reset()方法,但问题未解决。
问题原因
- 引用赋值修改了原对象:
onStartEditingMarket中直接将editedMarket赋值为传入的market对象,属于引用传递。修改editedMarket.region时,实际是直接修改了原market对象的属性,导致取消编辑后原数据已经被改变,下次编辑会显示修改后的值。 - ngModel与表单控件未同步重置:
mat-select绑定的是editedMarket.region(独立ngModel),而其他输入字段绑定的是表单控件。取消时仅重置了表单,但未同步恢复editedMarket的初始值。 - 取消逻辑未恢复初始状态:取消时仅将
editedMarket设为undefined,但未确保原对象的属性未被篡改,也未同步重置表单中对应区域控件的值。
解决方案
1. 编辑时创建原对象的深拷贝
编辑时不要直接引用原对象,而是创建深拷贝,避免修改原数据:
onStartEditingMarket(market: Market): void { // 用JSON序列化实现深拷贝(适用于无复杂类型的对象) this.editedMarket = JSON.parse(JSON.stringify(market)); // 若对象包含Date、函数等复杂类型,建议用lodash的_.cloneDeep // this.editedMarket = _.cloneDeep(market); }
2. 统一表单绑定方式(推荐)
将mat-select绑定到表单控件,替代独立ngModel,这样表单reset()时能统一重置所有字段:
修改mat-select代码:
<mat-select formControlName="region" [placeholder]="selectedRegion"> <mat-option [value]="null"> none </mat-option> <mat-option *ngFor="let region of marketRegions" [value]="region"> {{ region }} </mat-option> </mat-select>
取消时只需调用表单重置:
onCancelButtonClick() { this.editEntityForm.reset(); this.editedMarket = undefined; this.cancelEditingEntity.emit(); }
3. 完善取消逻辑的同步重置
如果坚持使用ngModel,取消时需同步恢复editedMarket的初始值,并重置表单对应控件:
onCancelEditingMarket(): void { // 恢复为原对象的拷贝,或直接重置region值 this.editedMarket = JSON.parse(JSON.stringify(this.entityOnEdit)); // 同步重置表单控件 this.editEntityForm.get('region')?.reset(this.entityOnEdit.region); }
4. 检查resetEditedEntity方法
确保该方法正确重置editedMarket和表单状态:
resetEditedEntity() { this.editedMarket = null; this.editEntityForm.reset(); }
内容的提问来源于stack exchange,提问作者Haidepzai
相关产品推荐
相关产品推荐

