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>
优化说明
- 全量标记重复项:通过
reduce统计每个值的出现次数,遍历数组给所有重复项标记错误,确保所有重复行都显示提示; - 移除实时排序:将数组排序逻辑移至保存操作前执行,避免校验时排序导致视图数据顺序变化,错误提示绑定错位;
- 空值校验优化:使用
some判断数组中是否存在空值,逻辑更简洁高效; - 字段绑定修正:修正原HTML中
ngModel绑定字段的笔误(原代码customer.value对应columnDisplayName,customer.order对应orderNum)。
内容的提问来源于stack exchange,提问作者Bhrungarajni
相关产品推荐
相关产品推荐

