Angular 5响应式表单如何仅在失焦时验证且实时更新字段值?
实现Angular 5响应式表单:实时更新值 + 仅失焦时验证
你遇到的问题其实是Angular表单updateOn: 'blur'的设计特性导致的——这个配置会同时延迟值的更新和验证触发到控件失焦时,显然和你需要实时计算的需求冲突。不过我们可以通过拆分这两个行为来实现目标:保持值实时更新,单独控制验证仅在失焦时执行。
核心思路
默认情况下,Angular表单控件的值会在每次输入(change事件)时实时更新,我们只需要让验证逻辑仅在控件失焦时才触发,同时确保错误提示只在控件被标记为touched后显示即可。
具体实现步骤
1. 初始化表单时不设置全局updateOn: 'blur'
保持表单控件的默认值更新行为(实时更新),只配置验证器:
import { FormBuilder, Validators, AbstractControl } from '@angular/forms'; // ... // 你的示例代码修改后: let formToMake = { purpose: [null, [Validators.required, 你的自定义验证器]], // 其他控件同理 }; this.form = this.fb.group(formToMake); // 不设置updateOn,保持默认change更新值
2. 在模板中绑定失焦事件,手动触发验证
给需要延迟验证的输入框绑定blur事件,在失焦时标记控件为touched并触发验证:
<!-- 输入框 --> <input type="text" formControlName="purpose" (blur)="triggerValidation(form.get('purpose'))" > <!-- 错误提示:仅当控件被标记为touched且验证不通过时显示 --> <div *ngIf="form.get('purpose').touched && form.get('purpose').invalid"> <span *ngIf="form.get('purpose').hasError('required')">此字段为必填项</span> <span *ngIf="form.get('purpose').hasError('你的自定义验证器key')">自定义错误提示</span> </div>
3. 在组件中实现验证触发方法
在组件类中编写triggerValidation方法,专门处理失焦时的验证逻辑:
triggerValidation(control: AbstractControl) { // 标记控件为已触碰(touched),用于控制错误提示的显示时机 control.markAsTouched(); // 触发验证,emitEvent设为false避免额外触发valueChanges(我们已经实时更新值了) control.updateValueAndValidity({ onlySelf: true, emitEvent: false }); }
进阶优化:封装指令复用逻辑
如果表单中有多个控件需要这个功能,重复写(blur)事件会很繁琐,可以封装一个自定义指令来复用逻辑:
import { Directive, HostListener, Input } from '@angular/core'; import { AbstractControl } from '@angular/forms'; @Directive({ selector: '[blurTriggerValidation]' }) export class BlurTriggerValidationDirective { @Input('blurTriggerValidation') control: AbstractControl; @HostListener('blur') onBlur() { if (this.control) { this.control.markAsTouched(); this.control.updateValueAndValidity({ onlySelf: true, emitEvent: false }); } } }
使用时只需在输入框上绑定指令和对应的控件:
<input type="text" formControlName="purpose" [blurTriggerValidation]="form.get('purpose')" >
为什么这个方案可行?
- 保持了控件值的实时更新(默认
change时机),你可以随时通过form.get('purpose').value获取最新值进行计算展示; - 仅在失焦时触发验证并标记控件为
touched,确保错误提示不会在用户输入过程中干扰体验; - 内置验证器和自定义验证器都能正常触发,不需要修改验证器本身的逻辑。
内容的提问来源于stack exchange,提问作者timfrans
相关产品推荐
相关产品推荐

