实现 Angular 中异步表单验证的 RxJS 解决方案

· 约 5 分钟读完

实现 Angular 中异步表单验证的 RxJS 解决方案

随着前端技术的不断发展,由于用户交互需求的复杂性提高,表单验证变得愈加必要。特别是在 Angular 中,表单验证更是应用广泛。但是, Angular 只提供了基础的验证器,对于异步表单验证却没有提供直接的支持。 在这里,我们将分享如何使用 RxJS 来解决 Angular 中的异步表单验证。

RxJS 是 Reactivex 的 JavaScript 版本,是一个处理异步事件流的库。RxJS 通过提供一系列的操作符和数据种类,简化了用 JavaScript 编写异步代码的难度,它的广泛运用在前端中,使异步编程更轻松。

在 Angular 中实现异步验证器的前置条件

在这里,我们有一个表单,包含两个字段,email 和 password 。需求是当 email 的值不为空时,它会向后端发送一个请求查询该 email 是否已经存在,如果已经存在,则显示错误提示,否则不显示。 在 Angular 中,实现异步表单验证的前置条件有两个:

1.创建异步验证器

首先,我们需要在组件内创建一个异步验证器。在这个例子中,我们需要创建一个函数名叫 checkEmail , 没有传入的参数,返回一个 Observable 。

2.为表单设置验证器

在模板中,通过给表单的 email 字段设置一个AsyncValidatorFn 进行实现。 AsyncValidatorFn 是一个函数,需要接受一个 FormControl 参数,并返回一个 Observable 。

通过对这两个前置条件进行实现,我们就可以完成基础的异步验证了。接下来,我们将在这个基础上,使用 RxJS 来实现异步表单验证。

使用 RxJS 实现异步表单验证

在实现异步验证器时,我们需要使用 RxJS 提供的一些操作符,包括 switchMap() , debounceTime() 和 distinctUntilChanged() 。 下面,我们会一一介绍并详细解释这些操作符的用法。

使用 switchMap() 操作符

在 angular 的异步验证控制下,如果未处理以前发出的 http 调用,多次验证器可能会同时发出大量请求,因此在这里我们选择如下函数:

这个函数会发送 http 请求获取 email 是否可用,返回上一步中提到的 Observable<boolean> 。

接下来,我们需要把这个函数添加到我们的异步验证器中。

在这个示例中,emailValidator() 方法返回了一个 AsyncValidatorFn 。 这个函数使用 switchMap() 操作符来返回响应式的 isValid$。

switchMap() 操作符能够解决 Angular 中的嵌套回调问题,它会将一个 Observable 转变为另一个 Observable ,并在过程中取消之前的 Observable ,即在新的 Observable 进入之前,取消与上个 Observable 相关的任务。 在这里,通过使用 debounceTime() 和 distinctUntilChanged() 操作符,我们可以限制性地逐渐发出请求。

使用 debounceTime() 和 distinctUntilChanged() 操作符

debounceTime() 操作符会等待一段时间(在这里是 500ms)以确保用户停止输入并发送请求。如果一致输入,它会取消先前等待的时间,重新开始计时以等待特定的时间换新后再发出请求。如果没有新的项被发出,subscribeaction 就不会被调用。

distinctUntilChanged() 操作符则在发射进行比较并且当前的值如果与上一个值相同就不会被发射。它的目的是,接收到相同的值时只会执行一次并且避免不必要的调用。

在最后的行中,我们使用 map() 操作符将结果转换为我们需要的对象结构。如果 email 可用,则返回 null 。如果 email 不可用,最终 Observable 返回 { emailTaken: true } 。这个错误消息可以在模板中处理。

通过实现这个异步验证器,我们可以大大的提高 Angular 中关于表单的验证功能,使验证过程更加的严谨和全面,从而增强了开发的体验。同时,这份代码也可以帮助初学者更好的理解 RxJS 的操作符,并在实际编程中获得更好的实践指导。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7907da941bf7134d88a1a