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

Mat Dialog内嵌Mat Table点击addRow时行取值相同问题

问题复现流程
  • 页面初始加载内置Mat Table,展示状态正常
    页面初始表格正常效果
  • 触发交互打开Mat Dialog弹窗,弹窗内加载带数据列表的Mat Table,初始加载状态正常
    弹窗内表格初始加载效果
  • 点击addRow按钮新增表格行时,新增行直接复用已有行取值,出现全表行数据联动异常:第一行已填/已选值无法保留,第二行选值会同步覆盖首行数据,各行无法独立维护数据
    新增行数据联动异常效果

核心诉求:新增行时保留已有行的填写内容,支持各行独立维护数据,解决数据联动覆盖问题。

问题原因

核心是对象引用共用:

  1. 新增行时直接把已有行的对象引用推入数据源数组,多行绑定同一个内存地址的对象,任意行修改字段会同步影响所有绑定该对象的行
  2. 如果用响应式表单实现行编辑,新增行时直接复用已有行的FormGroup/FormControl实例,没有新建独立控件,也会导致数据联动
  3. 表格未配置trackBy时,Angular DOM节点复用错误也可能偶发控件状态串改
修复方案

1. 新增行时初始化独立数据对象

禁止直接复用已有行对象引用,新行必须生成独立对象,嵌套引用类型做深拷贝:

// 错误写法:直接push已有行对象,导致引用共用
addRow() {
  this.dataSource.data.push(this.dataSource.data.at(-1))
}

// 正确写法:新建独立对象
addRow() {
  const newRow = {
    id: Date.now(), // 生成唯一行标识
    selectVal: null,
    inputVal: '',
    // 有嵌套对象时用深拷贝,例:
    // extend: JSON.parse(JSON.stringify(lastRow.extend))
  }
  this.dataSource.data = [...this.dataSource.data, newRow]
}

2. 表单场景新建独立控件实例

用响应式表单FormArray实现行编辑时,新增行必须生成全新的FormGroup实例,禁止直接推入已有FormGroup:

// 抽离单行表单初始化方法
initRowForm(defaultVal?: any): FormGroup {
  return this.fb.group({
    selectVal: [defaultVal?.selectVal || null],
    inputVal: [defaultVal?.inputVal || '']
  })
}

addFormRow() {
  const rowArr = this.form.get('rowList') as FormArray
  // 每次新增都生成新的FormGroup实例
  rowArr.push(this.initRowForm())
}

3. 配置表格trackBy函数

给Mat Table配置trackBy,用行唯一标识追踪行状态,避免DOM错误复用:

<table mat-table [dataSource]="dataSource" [trackBy]="rowTrackBy">
  <!-- 列定义省略 -->
</table>
rowTrackBy(index: number, row: any) {
  // 优先用行唯一ID,没有就用索引
  return row.id || index
}

内容的提问来源于stack exchange,提问作者Yan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:39:34