Angular表单验证异常触发问题:仅需失焦时触发验证(Tab页场景)
解决Angular表单仅在失焦时触发验证的问题
针对你遇到的「点击无关按钮也显示验证提示」的问题,以下是两种可行的解决方案,确保验证仅在输入框失焦(focusout)时触发:
方案一:利用Angular表单的updateOn配置(简单快捷)
Angular FormControl支持通过updateOn指定验证触发时机,设置为'blur'即可让验证仅在控件失焦时执行:
1. 修改FormControl初始化代码
occupation: new FormControl('', { validators: [Validators.required, this.validationService.invalidNameFormat.bind(this)], updateOn: 'blur' // 指定验证仅在失焦时触发 }),
2. 模板优化(可选)
如果无关按钮存在触发表单markAllAsTouched()的逻辑,可能仍会触发错误提示。此时可以给mat-error增加touched状态判断:
<mat-error *ngIf="dataEntryMainFormGroup.get('occupation').touched && dataEntryMainFormGroup.get('occupation').hasError('required') "> {{msgConfig.td_data_entry_required_occupation}} </mat-error> <mat-error *ngIf="dataEntryMainFormGroup.get('occupation').touched && dataEntryMainFormGroup.get('occupation').hasError('invalidNameFormat') "> {{msgConfig.td_registration_validation_invalid_occupation}} </mat-error>
方案二:手动控制验证触发与错误显示(完全可控)
如果需要更精细的控制(比如Tab页切换时不强制验证),可以手动管理验证逻辑和错误显示的触发条件:
1. 移除同步验证器,添加状态标记
在组件类中初始化FormControl时暂不添加验证器,同时添加一个对象存储控件的验证触发状态:
// 初始化空控件,不绑定同步验证器 occupation: new FormControl(''), // 记录每个控件是否已触发过失焦验证 controlValidatedOnBlur: { [key: string]: boolean } = { occupation: false };
2. 修改onFocusOutEvent方法,手动触发验证
在失焦时动态添加验证器并执行验证:
onFocusOutEvent(event: FocusEvent, controlName: string) { const control = this.dataEntryMainFormGroup.get(controlName); if (!control) return; // 绑定验证器并更新验证状态 control.setValidators([Validators.required, this.validationService.invalidNameFormat.bind(this)]); control.updateValueAndValidity({ emitEvent: false }); // 标记该控件已触发过失焦验证 this.controlValidatedOnBlur[controlName] = true; }
3. 更新模板中的错误显示条件
仅当控件已触发过失焦验证且存在错误时,才显示mat-error:
<mat-form-field class="mat-width-98" appearance="outline"> <mat-label>Profession Occupation/ Job</mat-label> <input matInput placeholder="Profession Occupation/ Job" formControlName="occupation" (focusout)="onFocusOutEvent($event, 'occupation')" [ngClass]="isMatched('occupation') ? '' : 'input-highlight'" maxlength="{{moduleConfig.td_reg_occupation_length}}"> <mat-error *ngIf="controlValidatedOnBlur['occupation'] && dataEntryMainFormGroup.get('occupation').hasError('required') "> {{msgConfig.td_data_entry_required_occupation}} </mat-error> <mat-error *ngIf="controlValidatedOnBlur['occupation'] && dataEntryMainFormGroup.get('occupation').hasError('invalidNameFormat') "> {{msgConfig.td_registration_validation_invalid_occupation}} </mat-error> </mat-form-field>
Tab页场景适配
两种方案都能兼容Tab页场景:
- 若切换Tab时输入框处于聚焦状态,会触发
focusout事件,自动执行验证; - 若输入框从未被聚焦过,不会触发验证,也不会显示错误提示,符合需求。
内容的提问来源于stack exchange,提问作者Ashrik Ahamed
相关产品推荐
相关产品推荐

