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

AngularJS中ng-change切换选项后新增行复用旧值问题求助

问题根源分析

我一眼就看出问题出在哪了——你现在所有行的表单控件都绑定了同一个全局的payment_data对象,下拉框的ng-model也没和当前行的条目关联起来!这样一来,新增行时会直接继承全局变量的旧值,甚至切换任意一行的下拉框,所有行的输入框都会同步变化,完全达不到每行独立的效果。

修复方案

我们需要把每一行的下拉框和输入框都绑定到form.payments数组里的当前行对象上,让各行数据彻底独立。具体修改如下:

1. 调整HTML控件的绑定(核心修改)

假设你的表格行是在ng-repeat="payment in form.payments"循环中,修改每个控件的ng-model:

<!-- 下拉框:绑定到当前行的payment.invoice,避免全局共享 -->
<td class="minwd100"> 
  <select class="form-control" id="invoice_id_{{$index}}" name="invoice_id_{{$index}}" 
          ng-options="invoice as invoice.invoice_number+ ' - '+invoice.client_name+' - '+invoice.invoice_converted_total for invoice in approved_invoices track by invoice.invoice_id" 
          ng-model="payment.invoice" 
          ng-change="changeInvoice(payment)">
  </select> 
</td> 
<!-- 付款金额:绑定到当前payment的独立属性 -->
<td class="minwd100">
  <input type="text" class="form-control" id="payment_amount_{{$index}}" 
         ng-model="payment.payment_amount" 
         name="payment_amount_{{$index}}" 
         placeholder="Enter {{form_data.payment_amount.label}}" 
         ng-focus="form_data.payment_amount.error = ''" />
</td> 
<!-- 汇率:绑定到当前payment的独立属性 -->
<td class="minwd100">
  <input type="text" class="form-control" id="payment_conversion_{{$index}}" 
         ng-model="payment.payment_conversion_rate" 
         name="payment_conversion_{{$index}}" 
         placeholder="Enter {{form_data.payment_conversion_rate.label}}" 
         ng-focus="form_data.payment_conversion_rate.error = ''" />
</td> 
<!-- 转换后金额:绑定到当前payment的独立属性 -->
<td class="minwd100">
  <input type="text" class="form-control" id="payment_converted_amount_{{$index}}" 
         ng-model="payment.payment_converted_amount" 
         name="payment_converted_amount_{{$index}}" 
         placeholder="Enter {{form_data.payment_converted_amount.label}}" 
         ng-focus="form_data.payment_converted_amount.error = ''" 
         ng-readonly="true"/>
</td> 
<td class="wd80"> 
  <div class="dt-options"> 
    <a href ng-if="$index === form.payments.length - 1" ng-click="addContact()" title="Add Contact"><i class="fa fa-plus fa-lg"></i></a> 
    <a href ng-if="form.payments.length > 1" ng-click="removeContact($index)" title="Remove Contact"><i class="fa fa-trash-o fa-lg"></i></a> 
  </div> 
</td>

小贴士:给每个控件的id和name加上_{{$index}},确保每行的控件ID唯一,避免DOM冲突。

2. 更新JS函数逻辑

修改changeInvoice和addContact,让它们操作当前行的独立对象:

// 传入当前行的payment对象,只更新该行的属性
$scope.changeInvoice = function (payment){
  if (!payment.invoice) return; // 处理未选中选项的边界情况
  payment.payment_amount = payment.invoice.invoice_converted_total;
  payment.payment_conversion_rate = payment.invoice.invoice_conversion_rate;
  payment.payment_converted_amount = payment.invoice.invoice_converted_balance;
  $scope.client_id = payment.invoice.client_id;
  payment.invoice_id = payment.invoice.invoice_id; // 把选中的发票ID存到当前行对象中
};

// 新增行时初始化独立的空结构,避免继承旧值
$scope.addContact = function() {
  $scope.form.payments.push({
    invoice_id: '', 
    invoice: null, // 预留选中发票对象的位置
    payment_amount: '', 
    payment_conversion_rate: '', 
    payment_converted_amount: ''
  });
};

$scope.removeContact = function(index) {
  $scope.form.payments.splice(index, 1);
};

3. 修复原理说明

  • 每一行的控件都绑定到form.payments数组中对应的单个对象,各行数据完全独立,不会互相干扰。
  • 切换下拉框时,changeInvoice只更新当前行的属性,其他行不受影响。
  • 新增行时初始化了全新的空对象,不会再继承全局变量的旧值。
额外优化建议

如果觉得ng-options里的显示文本太冗长,可以提取一个过滤器简化HTML:

// 定义一个自定义过滤器
app.filter('invoiceDisplay', function() {
  return function(invoice) {
    return `${invoice.invoice_number} - ${invoice.client_name} - ${invoice.invoice_converted_total}`;
  };
});

然后在HTML中使用:

ng-options="invoice as (invoice | invoiceDisplay) for invoice in approved_invoices track by invoice.invoice_id"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:49:05