angular如何实现异步验证防抖
小编给大家分享一下angular如何实现异步验证防抖,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
前言
本周的一个需求是在一个异步验证上加上防抖,防抖,以前也接触过,依稀记得不难,就没再去看angluar的官方文档,直接就开始google写了,然后……一不小心就掉坑里了。
突然没了效果的验证功能
在网上一番查询以后,选了一个最简单,最符合的实现
一番修改以后我的代码成了下面这样
public oldPasswordValidator(): AsyncValidatorFn {
return (ctrl: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
rerutn ctrl.valueChanges.pipe(
debounceTime(2000),
distinctUntilChanged(),
switchMap(value => this.checkPasswordIsRight(value)),
map((isRight: boolean) => (isRight ? null : {passwordError: true})),
catchError(() => null));
};
但是验证器并没有效果,在c层获取到的始终是null,而在方法中打印结果,却可以发现,能够产生正确的结果
但是获取到的相关错误一直是没有,更让我感到惊讶的是表单的valid和invalid竟然同时处在了false,他们不是应该互斥吗?不是反义词吗?
FormControl的status
首先还是解决valid与invalid的疑惑吧,查询官方文档。
FormControl的status继承自AbstractControl
AbstractControl是 FormControl、FormGroup 和 FormArray 的基类。它提供了一些所有控件和控件组共有的行为,比如运行验证器、计算状态和重置状态。 它还定义了一些所有子类共享的属性,如 value、valid 和 dirty。不允许直接实例化它。
找到valid
至此,这个疑问解决了,互斥的并不仅仅是valid和invalid,
还有一个检查进行状态:pending和禁止disable,验证一下,果然此时的状态是在pending
为何会一直在pending状态?
接着查看表单验证的官方文档
自定义异步验证器和同步验证器很像,只是它们必须返回一个稍后会输出 null 或“验证错误对象”的承诺(Promise)或可观察对象,如果是可观察对象,那么它必须在某个时间点被完成(complete),那时候这个表单就会使用它输出的最后一个值作为验证结果。(译注:HTTP 服务是自动完成的,但是某些自定义的可观察对象可能需要手动调用 complete 方法)
返回的可观察对象必须是有限的,也就是说,它必须在某个时间点结束(complete)。要把无尽的可观察对象转换成有限的,可以使用 first、last、take 或 takeUntil 等过滤型管道对其进行处理。
结果很明显了,上面的观察者对象是通过valueChangs产生的, 被人订阅后,并不会主动的调用complete()方法,而会不停的发布新值。下面的例子可以看出来
给他加个first()让他只返回第一个结果,果然好使了:
first(predicate: function(value: T, index: number, source: Observable<T>): boolean, resultSelector:function(value: T, index: number): R, defaultValue: R): Observable<T | R>
只发出由源 Observable 所发出的值中第一个(或第一个满足条件的值)。
如果你足够细心
看的太不仔细了,到解决这个问题之前,一直都没发现……
一个更简单的实现方式
验证的防抖功能实际上并不需要通过上面的方式实现,尽管上面也并不困难。
最简单的防抖方式,在官方文档已经提供了:
默认情况下,每当表单值变化之后,都会执行所有验证器。对于同步验证器,没有什么会显著影响应用性能的地方。不过,异步验证器通常会执行某种 HTTP 请求来对控件进行验证。如果在每次按键之后都发出 HTTP 请求会给后端 API 带来沉重的负担,应该尽量避免。
我们可以把updateOn属性从change(默认值)改成submit或blur来推迟表单验证的更新时机。
initForm() {
this.modifyPasswordForm = this.fb.group({
oldPassword: [null, [Validators.required], [this.userService.oldPasswordValidator()]],
newPassword: [null, Validators.required],
confirmNewPassword: [null, Validators.required]
// updateOn 作用是在什么时候更新表单数据
// https://angular.cn/guide/form-validation#note-on-performance
}, {updateOn: 'blur'},
);
}
以上是“angular如何实现异步验证防抖”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341