Angular响应式表单name输入框验证持续处于pending状态问题
Angular响应式表单name输入框始终处于pending状态问题排查
问题现象
使用Angular响应式表单时,name输入框触发touched验证后始终处于pending状态,其余输入框验证功能正常,无法定位问题原因。输入字符后,控制台输出的input标签带有ng-pending类:
<input _ngcontent-sfk-c51="" formcontrolname="productName" type="text" productname="productName" id="productName" placeholder="productName" ng-reflect-name="productName" class="ng-touched ng-dirty ng-pending">
相关代码
TS组件代码
ngOnInit(): void { this.signupForm = this.formBuilder.group({ name: [ '', [ Validators.required, Validators.minLength(3), Validators.pattern('^[a-zA-Z ]*$'), ], ], familyName: [ '', [ Validators.required, Validators.minLength(3), Validators.pattern('^[a-zA-Z ]*$'), ], ], number: [ '', Validators.required, Validators.pattern('[0-9]{3} [0-9]{3} [0-9]{3}'), ], email: ['', [Validators.required, Validators.email]], password: [ '', [ Validators.required, Validators.pattern('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$'), ], ], }); }
HTML模板代码
<div class="container"> <form [formGroup]="signupForm" (ngSubmit)="onSubmit()"> <label for="name">Name </label> <input formControlName="name" type="text" name="name" id="name" placeholder="Name" /> <div class="alert-danger" *ngIf="name?.touched && name?.invalid"> Name is not valid </div> <label for="familyName">Family Name </label> <input formControlName="familyName" type="text" name="familyName" id="familyName" placeholder="Family Name" /> <div class="alert-danger" *ngIf="familyName?.touched && familyName?.invalid" > Family Name is not valid </div> <label for="number">Phone number </label> <input formControlName="number" type="text" name="number" id="number" placeholder="Phone number" /> <div class="alert-danger" *ngIf="number?.touched && number?.invalid"> Phone Number is not valid </div> <label for="email">Email </label> <input formControlName="email" type="text" name="email" id="email" placeholder="email" /> <div class="alert-danger" *ngIf="email?.touched && email?.invalid"> Email is not valid </div> <label for="password">Password </label> <input formControlName="password" type="text" name="password" id="password" placeholder="password" /> <div class="alert-danger" *ngIf="password?.touched && password?.invalid"> Password should have minimum 8 characters, at least 1 uppercase letter, 1 lowercase letter and 1 number </div> <input class="submit-btn" type="submit" /> </form> </div>
问题排查与解决方案
1. 表单控件名称不匹配
控制台输出的input标签中formcontrolname="productName",但TS代码中表单控件名为name,HTML模板中formControlName="name",存在名称不一致问题。请检查代码中是否存在拼写错误,确保表单控件名称、模板中的formControlName属性完全一致。
2. 同步验证器写法错误
TS代码中number字段的验证器未包裹在数组中:
number: [ '', Validators.required, Validators.pattern('[0-9]{3} [0-9]{3} [0-9]{3}'), ],
Angular的FormControl构造函数中,第二个参数为同步验证器(单个或数组),第三个参数为异步验证器。此处将Validators.pattern作为第三个参数传入,被识别为异步验证器,但它是同步验证器,会导致控件一直处于pending状态。修正为:
number: [ '', [Validators.required, Validators.pattern('[0-9]{3} [0-9]{3} [0-9]{3}')], ],
若name字段存在同样的写法错误,也会导致其处于pending状态,请同步检查。
3. 未定义表单控件getter
HTML模板中使用name?.touched、familyName?.touched等语法,但TS代码中未定义对应的getter方法,导致模板无法正确访问表单控件。需在组件中添加以下getter:
get name() { return this.signupForm.get('name'); } get familyName() { return this.signupForm.get('familyName'); } get number() { return this.signupForm.get('number'); } get email() { return this.signupForm.get('email'); } get password() { return this.signupForm.get('password'); }
内容的提问来源于stack exchange,提问作者Antonio Florian
相关产品推荐
相关产品推荐

