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

AngularJS ng-repeat表格上方展示验证错误问题求助

解决AngularJS ng-repeat表格中统一显示验证错误的问题

我之前处理过类似的AngularJS表单验证场景,你的核心痛点在于ng-repeat循环中重复的表单控件name属性导致父表单无法正确追踪每个控件的验证状态——父表单里同名的控件会被覆盖或变成数组,根本没法精准判断哪一行的输入出了问题。下面是具体的解决方案,一步步帮你搞定:

1. 为每行创建独立的行级表单

首先要给ng-repeat的每行绑定一个独立的表单对象,这样每个输入控件的验证状态都会被单独记录。你之前试过加ng-form但没生效,大概率是没把行表单的引用收集起来,没法在父容器里判断全局错误。

修改表格行的代码,把行表单绑定到控制器里的数组:

<form name="equipmentDuplicatesForm" novalidate>
  <!-- 错误提示区域放在这里 -->
  <table>
    <tbody infinite-scroll="loadMore()">
      <tr ng-repeat="row in duplicatesArray" 
          ng-click="selectedDuplicateIndex=$index;" 
          ng-class="{selected: $index === selectedDuplicateIndex}"
          ng-form="rowForms[$index]"> <!-- 将行表单存入数组 -->
        <!-- 省略其他单元格 -->
        <td>
          <div class="col-xs-12">
            <input type="text" 
                   name="assetNo" 
                   ng-model="row.assetNo" 
                   class="form-control" 
                   ng-change="checkAssetNo(row)" 
                   ng-maxlength="100" 
                   sm-duplicate-validator 
                   validate-duplicates="true" 
                   error-message="row.errorMessage" 
                   api-method="api/rentalEquipments/checkForDuplicate" 
                   primary-key-value="row.equipmentId" 
                   ng-model-options="{ debounce: { default : 500, blur: 0 }}" />
          </div>
        </td>
        <td>
          <input type="text" 
                 name="serialNo1" 
                 ng-model="row.serialNo1" 
                 class="form-control" 
                 ng-maxlength="100" />
        </td>
      </tr>
    </tbody>
  </table>
</form>

注意:去掉循环中input的重复id属性(比如你之前的id="assetNo"),HTML里id必须唯一,重复id会导致DOM选择器混乱。

2. 在控制器中收集并判断全局错误状态

在控制器里定义一个数组存储所有行表单,再写几个工具函数判断是否存在任意一行的验证错误:

$scope.rowForms = []; // 存储每行的表单对象

// 判断是否存在任何错误(用于控制错误提示区域的显示)
$scope.hasAnyError = function() {
  return $scope.hasAnyDuplicateError() || $scope.hasAnyAssetNoMaxlengthError() || $scope.hasAnySerialNoMaxlengthError();
};

// 判断是否有资产编号超长
$scope.hasAnyAssetNoMaxlengthError = function() {
  return $scope.rowForms.some(function(form) {
    return form && form.assetNo && form.assetNo.$error.maxlength;
  });
};

// 判断是否有序列号超长
$scope.hasAnySerialNoMaxlengthError = function() {
  return $scope.rowForms.some(function(form) {
    return form && form.serialNo1 && form.serialNo1.$error.maxlength;
  });
};

// 判断是否有重复错误
$scope.hasAnyDuplicateError = function() {
  return $scope.rowForms.some(function(form) {
    return form && form.assetNo && (form.assetNo.$error.smDuplicate || form.assetNo.$error.duplicate);
  });
};

// 删除行时同步维护行表单数组
$scope.removeRow = function(index) {
  $scope.duplicatesArray.splice(index, 1);
  $scope.rowForms.splice(index, 1);
};

3. 调整错误提示区域的逻辑

把原来的错误提示区域改成用上面的工具函数判断显示,这样就能在表格上方统一展示全局错误:

<div class="col-xs-12" ng-show="hasAnyError()">
  <div class="info-text-block info-text-block-error">
    <p ng-show="hasAnyDuplicateError()">
      {{getDuplicateError()}}
    </p>
    <p ng-show="hasAnyAssetNoMaxlengthError()">
      @string.Format(Messages.cannotExceed, Labels.assetNo, "100")
    </p>
    <p ng-show="hasAnySerialNoMaxlengthError()">
      @string.Format(Messages.cannotExceed, Labels.serialNo1, "100")
    </p>
  </div>
</div>

4. 确保自定义重复验证指令正确标记行级错误

你的sm-duplicate-validator自定义指令需要确保错误状态标记在当前行的表单控件上,而不是父表单。指令核心逻辑大概是这样的(如果还没调整的话):

app.directive('smDuplicateValidator', function($http, $q) {
  return {
    require: 'ngModel',
    scope: {
      validateDuplicates: '=',
      apiMethod: '@',
      primaryKeyValue: '@'
    },
    link: function(scope, element, attrs, ngModel) {
      // 异步验证逻辑
      ngModel.$asyncValidators.smDuplicate = function(modelValue, viewValue) {
        if (!scope.validateDuplicates || !modelValue) {
          return $q.resolve();
        }
        return $http.post(scope.apiMethod, {
          value: modelValue,
          primaryKey: scope.primaryKeyValue
        }).then(function(response) {
          return response.data.isDuplicate ? $q.reject('duplicate') : $q.resolve();
        });
      };
    }
  };
});

这个指令会把重复错误标记到当前行表单的assetNo控件上,这样rowForms[$index].assetNo.$error.smDuplicate就能正确返回状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:42:45