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

Angular动态网格行内动态新增表单元素的valueChanges仅影响最后一行问题

问题根因

代码的核心问题是循环中复用了类全局的this.formGroup变量,每次循环迭代都会覆盖这个变量的值,而valueChanges的订阅回调是异步触发的,闭包引用的this.formGroup最终会指向循环结束后的最后一行表单实例,所以所有行的下拉变化都只会操作最后一行的输入框。

修复方案

不需要用全局变量存储当前行表单,直接在循环作用域内声明局部变量存储每行的表单实例,确保每个订阅回调绑定的是当前迭代的表单对象即可,修改后代码如下:

public editRows(grid: GridComponent) {
  let currentRow = 0;
  const rows = grid.data;
  const itemsFormArray = this.formGroups.get('items') as FormArray;
  // 建议用rows.length代替硬编码6,避免数据量不足时报错
  for (let i = 0; i < rows.length; i++) {
    // 声明局部变量存储当前行表单,不要用this.formGroup全局变量
    const rowForm = this.createFormGroup(rows[i]);
    itemsFormArray.push(rowForm);
    
    grid.editRow(currentRow, rowForm, {skipFocus: true});
    currentRow++;
    
    // 初始化禁用状态
    if(rowForm.controls.dataType.value !== 'Value List') {
      rowForm.get('inputValues').disable();
    }

    // 订阅当前行的下拉变化,闭包绑定的是当前循环的rowForm实例,不会被后续迭代覆盖
    rowForm.get('dataType').valueChanges.subscribe(selectedValue => {
      if(selectedValue !== 'Value List') {
        rowForm.get('inputValues').disable();
      } else {
        rowForm.get('inputValues').enable();
      }
    }); 
  }
}

额外优化建议

  • 每次进入编辑模式前先清空items FormArray的旧控件,避免重复累加表单实例
  • 组件销毁时要取消所有valueChanges的订阅,避免内存泄漏,可以用一个订阅数组存储所有订阅,在ngOnDestroy钩子中统一取消:
private subscriptions: Subscription[] = [];

// 订阅时将实例push到数组
this.subscriptions.push(rowForm.get('dataType').valueChanges.subscribe(...));

// 组件销毁时统一取消订阅
ngOnDestroy() {
  this.subscriptions.forEach(sub => sub.unsubscribe());
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:54:04