Angular 7:自定义异步验证器 [英] Angular 7: Custom Async Validator

查看:185
本文介绍了Angular 7:自定义异步验证器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的注册表单创建一个自定义的异步验证器,它在其中检查电子邮件是否已经存在.如果电子邮件不存在,则后端返回404,如果电子邮件不存在,则返回200(无法更改此旧代码).

I'm trying to create a custom async validator for my registration form where it checks if an email already exists. The backend returns 404 if the email does not exist and 200 if it does exist (can't change this old code).

我找到了一些教程,但是没有使用最新的rxjs库.我创建了这个Validation类:

I have found a couple tutorials but didn't find one using the latest rxjs library. I created this Validation class:

export class UniqueEmailValidator {
    static createValidator(httpClient: HttpClient, degree: number, wlId: number) {
        return (control: AbstractControl) => {
            return httpClient.get(`${url}?degree=${degree}&email=${control.value}&wl_id=${wlId}`)
                .pipe(
                    map(
                        (response: Response) => {
                            return response.status === 404 ? null : { emailNotUnique: true };
                        }
                    )
                );
        };
    }
}

并在我的ts文件中创建我正在使用的表单

and in my ts file creating the form I'm using this

this.registerForm = this.fb.group({
            email: ['', [Validators.required, Validators.email], UniqueEmailValidator.createValidator(
                this.httpClient, this.wlService.wl.degree, this.wlService.wl.id)],

xhr调用已完成并正确返回,但电子邮件的表单控件保持为待处理状态.对我做错了什么主意吗?

The xhr call is being done and returned correctly but the form control of email is staying as pending. Any ideas on what I did wrong?

推荐答案

经过一段时间的研究,终于弄清楚了.

Figured it out after a while and more research.

验证类别:

@Injectable()
export class UniqueEmailValidator {
    constructor(private http: HttpClient) {}

    searchEmail(email: string, degree: number, wlId: number) {
        return timer(1000)
            .pipe(
                switchMap(() => {
                    // Check if email is unique
                    return this.http.get<any>(`${url}?degree=${degree}&email=${email}&wl_id=${wlId}`);
                })
            );
    }

    createValidator(degree: number, wlId: number): AsyncValidatorFn {
        return (control: AbstractControl): Observable<{ [key: string]: any } | null> => {
            return this.searchEmail(control.value, degree, wlId)
                .pipe(
                    map(
                        (response: Response) => {
                            return null;
                        },
                    ),
                    catchError(
                        (err: any) => {
                            return err.status === 404 ? of(null) : of({ emailNotUnique: true });
                        },
                    ),
                );
        };
    }
}

不确定计时器是否可以更改,但是我在文章中找到了它,并且可以正常工作.很乐意对此进行确认.

Not sure if timer can be changed but I found it in an article and it works fine. Would love some confirmation on that.

基本上,我正在执行catchError,因为来自后端的响应返回404并再次从catchError返回一个可观察的对象.

Basically I'm doing a catchError since the response from the backend returns 404 and returning an observable again from the catchError.

然后在创建表单的过程中:

Then in the form creation I'm doing:

        this.registerForm = this.fb.group({
            email: ['', [Validators.required, Validators.email], this.uniqueEmailValidator.createValidator(
            this.wlService.wl.degree, this.wlService.wl.id
        )],

然后我在模块中添加了UniqueEmailValidator作为提供程序,并注入了此组件构造函数中.

And I added the UniqueEmailValidator as a provider in the module and injected in this component constructor.

这篇关于Angular 7:自定义异步验证器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆