如何在ngx-formly中实现带防抖的验证?配置debounce后校验即时触发求解
你描述的现象属于预期行为,并非ngx-formly的bug。
原因说明
ngx-formly中modelOptions.debounce默认仅作用于表单绑定的model对象的更新时机,不会修改Angular原生FormControl的更新逻辑。而表单验证的触发依赖FormControl的值变更事件,所以只要输入框内容发生变化,验证就会立刻执行,和model的防抖更新是相互独立的两个逻辑,因此会出现“验证立即执行、model延迟更新”的表现。
实现校验防抖的两种方案
方案1:配置FormControl全局更新规则(更简单)
在字段的modelOptions中新增updateOn: 'change'配置,让FormControl本身的值更新也遵循防抖规则,绑定在其上的同步验证器自然也会延迟触发:
fields: FormlyFieldConfig[] = [ { key: 'text', type: 'input', modelOptions: { updateOn: 'change', // 新增这一行配置 debounce: { default: 2000, }, }, templateOptions: { label: 'Debounce', }, validators: ["test"] }, ];
该方案无需修改原有验证器逻辑,同时可以保证FormControl的值更新和model更新时机一致。
方案2:改造为带防抖的异步验证器
如果不想修改FormControl的更新时机,可以把原本的同步验证器改造为异步验证器,通过rxjs操作符实现防抖:
- 首先修改FormlyConfig中的验证器配置:
import { of } from 'rxjs'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; { validationMessages: [ { name: 'test', message: "The value cannot be X", }, ], // 把原validators配置移到asyncValidators下 asyncValidators: [ { name: "test", validation: ((control: FormControl) => { return of(control.value).pipe( debounceTime(2000), // 自定义防抖时长 distinctUntilChanged(), // 输入值无变化时不重复触发验证 map(value => !!value || value === "X" ? null : {test: true}) ) }) } ] }
- 然后修改字段配置,把
validators: ["test"]替换为asyncValidators: ["test"]即可。
内容的提问来源于stack exchange,提问作者Salvatore Iovene
相关产品推荐
相关产品推荐

