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

如何重置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()方法,但问题未解决。


问题原因
  1. 引用赋值修改了原对象:onStartEditingMarket中直接将editedMarket赋值为传入的market对象,属于引用传递。修改editedMarket.region时,实际是直接修改了原market对象的属性,导致取消编辑后原数据已经被改变,下次编辑会显示修改后的值。
  2. ngModel与表单控件未同步重置:mat-select绑定的是editedMarket.region(独立ngModel),而其他输入字段绑定的是表单控件。取消时仅重置了表单,但未同步恢复editedMarket的初始值。
  3. 取消逻辑未恢复初始状态:取消时仅将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:24:09