Angular中ngFor+ngModel动态表单错误批量显示问题解决咨询
解决Angular动态表单输入框共享校验状态的问题
你猜的完全没错!问题就出在所有输入框共用了同一个name属性和重复的模板引用变量。Angular的模板驱动表单是通过name属性来识别每个表单控件的,当所有输入框都叫test时,NgForm会把它们当成同一个控件来管理,自然会出现一个出错全跟着报错的情况。
下面是具体的修复方案,我会一步步给你讲清楚:
1. 给每个输入框生成唯一的name属性
利用*ngFor循环里的index变量,给每个输入框的name拼接上索引值,确保每个控件的name独一无二:
<input [(ngModel)]="numbers[i].value" [name]="'test-' + i" matInput placeholder="Number input" #testInput="ngModel" pattern="^[0-9]{3}\.[0-9]{2}\.[0-9]{2}\.[0-9]{2}(\.[0-9]{2})?$" flex>
这里用了属性绑定[name]="'test-' + i",也可以用插值语法name="test-{{i}}",效果完全一致。
2. 调整模板引用变量(可选但更清晰)
虽然Angular在*ngFor循环里的模板变量是块级作用域,重复的变量名不会冲突,但为了代码可读性,你也可以给模板引用变量加上索引:
#testInput{{i}}="ngModel"
对应的错误提示也要同步修改:
<mat-error *ngIf="testInput{{i}}.errors?.pattern">No valid pattern</mat-error>
不过如果保持统一的变量名(比如#testInput="ngModel"),在循环的每个迭代里它也只会指向当前的输入框,所以这一步不是必须的,但统一命名会让代码更整洁。
修复后的完整代码
<form #form="ngForm" class="form"> <div layout="column" flex *ngFor="let item of numbers; let i = index"> <div layout="row" flex> <mat-form-field class="row-margin" flex> <input [(ngModel)]="numbers[i].value" [name]="'test-' + i" matInput placeholder="Number input" #testInput="ngModel" pattern="^[0-9]{3}\.[0-9]{2}\.[0-9]{2}\.[0-9]{2}(\.[0-9]{2})?$" flex> <mat-error *ngIf="testInput.errors?.pattern">No valid pattern</mat-error> </mat-form-field> <!-- only delete elements if list has more than one element --> <button *ngIf="i >= 1" mat-button (click)="deleteNumberFromList(i)">Delete</button> </div> </div> <mat-dialog-actions class="actions" layout="row"> <button type="submit" mat-button [disabled]="!form.valid" (click)="add()">Save</button> </mat-dialog-actions> </form>
额外提醒
注意你的正则表达式里的.,如果是要匹配字面量的点号,需要转义成\.(我已经在修复后的代码里改好了),否则.会匹配任意字符,这可能也会导致校验逻辑不符合预期。
这样修改之后,每个输入框就会拥有独立的校验状态,只有当前输入不符合规则的那个框才会显示错误提示,其他输入框不会受到影响。
内容的提问来源于stack exchange,提问作者Dev Db
相关产品推荐
相关产品推荐

