Angular响应式表单blur事件自动trim后校验不生效如何解决?
问题根因
- 你在
blur事件中仅修改了输入框的DOM属性值,没有同步更新Angular FormControl的内部存储值,校验器读取的是FormControl的缓存值而非DOM的实时值,所以trim后校验仍然不通过。 - 自定义校验器内直接调用
setValue会触发校验器重新执行,形成无限递归,才会抛出Maximum call stack size exceeded错误。
修复方案
1. 修改blur事件逻辑,同步更新FormControl值
不要直接修改DOM的value,调用FormControl的setValue方法更新trim后的值,Angular会自动触发重新校验:
leaving(event: Event) { const inputEle = event.target as HTMLInputElement; const trimmedVal = inputEle.value.trim(); // 同步值到FormControl,自动触发校验 this.myForm.get('title')?.setValue(trimmedVal); }
2. 优化校验规则(可选)
你可以直接针对trim后的值做长度校验,无需额外的NeedTrim校验器,避免重复判断:
this.myForm = this.formbuilder.group({ title: new FormControl("", [ Validators.required, // 自定义长度校验,直接基于trim后的值判断 (control: FormControl) => { const trimVal = (control.value || '').trim(); return trimVal.length >= 4 ? null : { minLength: { requiredLength: 4, actualLength: trimVal.length } }; } ]) });
如果你需要保留「禁止输入前后空格」的提示,也可以保留NeedTrim校验器,只要FormControl的值和DOM值同步,校验就会正常生效。
拓展方案(可选)
如果需要全局实现输入框自动trim,可以封装自定义指令或者实现ControlValueAccessor,无需每个输入框单独绑定blur事件。
内容的提问来源于stack exchange,提问作者Jeb50
相关产品推荐
相关产品推荐

