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

查看:24
本文介绍了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 库的教程.我创建了这个验证类:

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天全站免登陆