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

Angular12模板表单多行重复输入的错误提示异常问题排查

Angular 12 模板表单数组行内编辑重复校验问题

问题现象

在Angular 12中使用模板表单绑定数组并实现行内编辑时,遇到以下问题:

  • 当订单号(orderNum)或列显示名称(columnDisplayName)出现3条及以上重复数据时,仅其中一行会显示「Duplicate Entry」错误提示,其余重复行无提示;
  • 修改重复值为有效值后,错误提示会随数据排序位置发生偏移。

需求:实现所有重复行都显示错误提示,或提供更优实现方案。

现有代码问题分析

当前校验逻辑的核心问题:

  • 每次校验先清空所有错误标记,仅给当前触发校验的行标记错误,导致只有最后触发校验的重复行显示提示;
  • 仅通过some判断是否存在重复,未遍历所有行标记重复项;
  • 校验后立即对数组排序,导致视图数据顺序变化,错误提示绑定错位。

修正后的校验逻辑(TS代码)

// 订单号重复校验
public checkForDuplicate(event: any) {
  // 清空所有错误标记
  this.agentNotinView.forEach(x => x.error = false);
  
  // 统计每个订单号的出现次数
  const orderNumCount = this.agentNotinView.reduce((acc, item) => {
    const num = +item.orderNum;
    acc[num] = (acc[num] || 0) + 1;
    return acc;
  }, {} as Record<number, number>);

  // 给所有重复订单号的行标记错误
  this.agentNotinView.forEach(item => {
    const num = +item.orderNum;
    if (orderNumCount[num] > 1 && num) {
      item.error = true;
    }
  });

  // 检查是否存在空值,控制保存按钮状态
  this.disableSave = this.agentNotinView.some(item => !item.orderNum);
  
  // 建议将排序逻辑移至保存操作前执行,避免视图错位
  // this.agentNotinView = this.agentNotinView.sort((a, b) => +a.orderNum - +b.orderNum);
}

// 列显示名称重复校验
public checkForNameDuplicate(event: any) {
  // 清空所有错误标记
  this.agentNotinView.forEach(x => x.colerror = false);
  
  // 统计每个列名称的出现次数
  const nameCount = this.agentNotinView.reduce((acc, item) => {
    const name = item.columnDisplayName?.trim();
    acc[name] = (acc[name] || 0) + 1;
    return acc;
  }, {} as Record<string, number>);

  // 给所有重复名称的行标记错误
  this.agentNotinView.forEach(item => {
    const name = item.columnDisplayName?.trim();
    if (nameCount[name] > 1 && name) {
      item.colerror = true;
    }
  });

  // 检查是否存在空值,控制保存按钮状态
  this.disableSave = this.agentNotinView.some(item => !item.columnDisplayName?.trim());
}

修正后的HTML代码

<div class="row" *ngFor="let customer of agentNotinView">
  <div class="col-9">
    <input
      type="text"
      [(ngModel)]="customer.columnDisplayName"
      [ngModelOptions]="{ standalone: true }"
      (focusout)="checkForNameDuplicate(customer)"
      class="block form-control"
    />
    <span *ngIf="customer.colerror" class="text-danger">
      Duplicate Entry
    </span>
    <span
      *ngIf="!customer.columnDisplayName?.trim()"
      class="text-danger"
    >Cannot be empty</span>
  </div>
  <div class="col-3">
    <input
      type="text"
      [(ngModel)]="customer.orderNum"
      [ngModelOptions]="{ standalone: true }"
      class="w-50 block form-control"
      (focusout)="checkForDuplicate(customer)"
    />
    <span
      *ngIf="customer.error && customer.orderNum"
      class="text-danger"
    >
      Duplicate Entry
    </span>
    <span *ngIf="!customer.orderNum" class="text-danger"
    >Cannot be empty</span>
  </div>
</div>

优化说明

  1. 全量标记重复项:通过reduce统计每个值的出现次数,遍历数组给所有重复项标记错误,确保所有重复行都显示提示;
  2. 移除实时排序:将数组排序逻辑移至保存操作前执行,避免校验时排序导致视图数据顺序变化,错误提示绑定错位;
  3. 空值校验优化:使用some判断数组中是否存在空值,逻辑更简洁高效;
  4. 字段绑定修正:修正原HTML中ngModel绑定字段的笔误(原代码customer.value对应columnDisplayName,customer.order对应orderNum)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:50:17