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

AngularJS ng-repeat动态表单验证异常问题求助

解决AngularJS ng-repeat动态表单独立验证问题

嘿,刚接触AngularJS遇到这种动态表单验证的问题很正常,我帮你梳理下问题所在,再给你完整的解决方案!

先说说你代码里的核心问题

  1. ng-model语法错误:你写的myModel.['contbanca' + $index]多了个多余的点,而且用零散变量存多个账户信息太容易混乱,更推荐用数组结构管理。
  2. 重复的name和共用ng-model:所有重复项里的下拉框都用了name="banca",还绑定到同一个myModel.banca,这直接导致所有下拉框共享验证状态,自然会同步变化。
  3. 表单控件引用方式不对:userFieldForm.['contbanca' + $index]这种写法在AngularJS里会失效,应该去掉点,写成userFieldForm['contbanca' + $index]。
  4. 删除逻辑不精准:现在点击任何"X"都删最后一项,而不是当前点击的项,需要传递$index来指定删除位置。

完整解决方案

第一步:重构模型结构

把零散的变量改成数组,每个账户作为数组里的独立对象,方便管理和绑定:

app.controller('ValidationCtrl', ["$scope", "$state", "$timeout", "SweetAlert", function ($scope, $state, $timeout, SweetAlert) {
  // 初始化账户列表和对应模型
  $scope.banci = [{ id: '1' }, { id: '2' }];
  $scope.myModel = {
    banci: [{}, {}] // 每个元素对应一个账户的表单数据
  };

  $scope.addNewChoice = function () {
    if ($scope.banci.length === 6) {
      return;
    } else {
      var newItemNo = $scope.banci.length + 1;
      $scope.banci.push({ 'id': newItemNo.toString() });
      // 同步添加模型项,保持数据和视图一致
      $scope.myModel.banci.push({});
    }
  };

  $scope.removeChoice = function (index) {
    // 删除指定索引的项,精准操作当前表单
    $scope.banci.splice(index, 1);
    $scope.myModel.banci.splice(index, 1);
  };
}]);

第二步:修正HTML视图代码

重点修改控件的name、ng-model绑定,以及验证表达式:

<fieldset data-ng-repeat="(index, banca) in banci track by banca.id">
  <legend> Conturi bancare </legend>
  <ng-form name="userFieldForm">
    <!-- 账户号输入框 -->
    <div class="form-group" ng-class="{'has-error': userFieldForm['contbanca' + index].$dirty && userFieldForm['contbanca' + index].$invalid, 'has-success': userFieldForm['contbanca' + index].$valid}">
      <div class="col-md-4">
        <label class="control-label"> Cont banca {{index + 1}} <span class="symbol required"></span> </label>
        <input type="text" placeholder="Nr. Cont..." class="form-control" 
               name="contbanca{{index}}" 
               ng-model="myModel.banci[index].contbanca" 
               ng-pattern="/[a-zA-Z0-9]{24}/" required/>
        <span class="error text-small block" ng-if="userFieldForm['contbanca' + index].$dirty && userFieldForm['contbanca' + index].$error.required">Va rugam inserati numarul de cont!</span>
        <span class="error text-small block" ng-if="userFieldForm['contbanca' + index].$dirty && userFieldForm['contbanca' + index].$error.pattern">Numarul de cont trebuie sa aiba 24 de caractere alfanumerice!</span>
        <span class="success text-small block" ng-if="userFieldForm['contbanca' + index].$valid">Contul este valid!</span>
      </div>
    </div>

    <!-- 银行选择下拉框 -->
    <div class="form-group" ng-class="{'has-error': userFieldForm['banca' + index].$dirty && userFieldForm['banca' + index].$invalid, 'has-success': userFieldForm['banca' + index].$valid}">
      <div class="col-md-4">
        <label for="form-field-select-{{index}}"> Banca <span class="symbol required"></span> </label>
        <select class="form-control" 
                name="banca{{index}}" 
                ng-model="myModel.banci[index].banca" required>
          <option value="" disabled selected>Selectati banca &nbsp;</option>
          <option value="AlphaBank">Alpha Bank</option>
          <option value="AngloRomanianBank">Anglo-Romanian Bank</option>
          <option value="ATEBank">ATE Bank</option>
          <option value="BancaCRFirenze">Banca C.R. Firenze</option>
          <option value="BancaComercialaCarpatica">Banca Comerciala Carpatica</option>
          <option value="EximBank">Exim Bank</option>
          <option value="BancaDiRoma">Banca Di Roma</option>
          <option value="BancaItaloRomena">Banca Italo Romena</option>
          <option value="BancaRomaneasca">Banca Romaneasca</option>
          <option value="BancaTransilvania">Banca Transilvania</option>
          <option value="Bancpost">Bancpost</option>
          <option value="BCR">BCR</option>
          <option value="BRD">BRD - Groupe Societe Generale</option>
          <option value="CEC">CEC Bank</option>
          <option value="CitiBank">Citibank</option>
          <option value="CreditEuropeBank">Credit Europe Bank</option>
          <option value="EgnatiaBank">Egnatia Bank</option>
          <option value="EmporikiBank">Emporiki Bank</option>
          <option value="GarantiBank">Garanti Bank</option>
          <option value="HVBLocuinte">HVB Locuinte</option>
          <option value="INGBank">ING Bank</option>
          <option value="LaCaixa">La Caixa</option>
          <option value="LeumiBank">Leumi Bank</option>
          <option value="LibraBank">Libra Bank</option>
          <option value="MarfinBank">Marfin Bank</option>
          <option value="MilleniumBank">Millenium Bank</option>
          <option value="MKBRomexterraBank">MKB Romexterra Bank</option>
          <option value="OTPBank">OTP Bank</option>
          <option value="PiraeusBank">Piraeus Bank</option>
          <option value="PorscheBank">Porsche Bank</option>
          <option value="ProCreditBank">Pro Credit Bank</option>
          <option value="RaifaissenBank">Raifaissen Bank</option>
          <option value="RaifaissenLocuinte">Raifaissen Locuinte</option>
          <option value="RBS">RBS</option>
          <option value="RomanianInternationalBank">Romanian International Bank</option>
          <option value="SanpaoloImiBank">Sanpaolo Imi Bank</option>
          <option value="UniCreditTiriacBank">Unicredit Tiriac Bank</option>
          <option value="Volksbank">Volksbank</option>
        </select>
        <span class="error text-small block" ng-if="userFieldForm['banca' + index].$dirty && userFieldForm['banca' + index].$error.required">Va rugam selectati banca.</span>
        <span class="success text-small block" ng-if="userFieldForm['banca' + index].$valid">Banca selectata!</span>
      </div>
    </div>

    <!-- 货币选择下拉框 -->
    <div class="form-group" ng-class="{'has-error': userFieldForm['moneda' + index].$dirty && userFieldForm['moneda' + index].$invalid, 'has-success': userFieldForm['moneda' + index].$valid}">
      <div class="col-md-3">
        <label for="form-field-select-moneda-{{index}}"> Moneda <span class="symbol required"></span> </label>
        <select class="form-control" 
                name="moneda{{index}}" 
                ng-model="myModel.banci[index].moneda" required>
          <option value="" disabled selected>Selectati moneda &nbsp;</option>
          <option value="LEI">LEI</option>
          <option value="EURO">EURO</option>
          <option value="USD">USD</option>
        </select>
        <span class="error text-small block" ng-if="userFieldForm['moneda' + index].$dirty && userFieldForm['moneda' + index].$error.required">Va rugam selectati moneda.</span>
        <span class="success text-small block" ng-if="userFieldForm['moneda' + index].$valid">Moneda selectata!</span>
      </div>
    </div>

    <div class="col-md-1" style="margin-top: 22px;">
      <input type="button" value="X" class="btn btn-danger" ng-click="removeChoice(index)" />
    </div>
  </ng-form>
</fieldset>

<button class="btn btn-primary" ng-click="addNewChoice()" ng-disabled="banci.length === 6">Adauga cont bancar</button>

关键改动说明

  1. 用数组管理模型:myModel.banci数组里的每个对象对应一个账户的所有数据,确保每个表单项的模型完全独立。
  2. 唯一的控件name:每个控件的name都拼接了index,比如contbanca{{index}},这样每个控件在userFieldForm里都是独立的键,验证状态不会冲突。
  3. 精准删除逻辑:删除按钮传递当前项的index,控制器根据索引删除对应的列表项和模型项,避免数据不一致。
  4. track by优化渲染:ng-repeat里加上track by banca.id,可以避免AngularJS在添加删除项时出现重复渲染的问题。

这样修改后,每个动态生成的表单项都会有独立的验证状态,不会再出现同步的问题,模型数据也能正确存储每个账户的信息啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:02:06