如何使用异步呼叫使用验证器指令

发布于 2025-02-10 13:51:32 字数 1490 浏览 0 评论 0原文

我创建了一个验证器指令,该指令提出了HTTP请求,该请求检查是否已经存在电子邮件。

我可以看到API调用发生了,但是在模板中,验证不起作用

@Directive({
    selector:
        '[emailValidator][formControlName],[emailValidator][formControl],[emailValidator][ngModel]',
    providers: [
        {
            provide: NG_ASYNC_VALIDATORS,
            useExisting: forwardRef(() => EmailValidatorDirective),
            multi: true
        }
    ]
})
export class EmailValidatorDirective implements Validator {
    constructor(private _http: HttpService) {}

    validate(
        c: AbstractControl
    ): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
        return this.validateEmail(c.value);
    }

    private validateEmail(email: String): Observable<ValidationErrors | null> {
        return this._http.post('user/validate-email', { email }).pipe(
            debounceTime(500),
            distinctUntilChanged(),
            map((isUsed) => {
                // null no error, object for error
                return !isUsed
                    ? null
                    : {
                            isTaken: 'Email exists already.'
                      };
            })
        );
    }
}

模板:

<input
    id="email"
    type="email"
    class="form-control"
    formControlName="email"
    emailValidator
    placeholder="Enter E-mail Address"
/>

// always showing null
{{ formcontrol['email'].errors | json }}

I have created a validator directive that makes an HTTP request that checks if an email already exists.

I can see that the API call happening but in the template the validation is not working

Directive:

@Directive({
    selector:
        '[emailValidator][formControlName],[emailValidator][formControl],[emailValidator][ngModel]',
    providers: [
        {
            provide: NG_ASYNC_VALIDATORS,
            useExisting: forwardRef(() => EmailValidatorDirective),
            multi: true
        }
    ]
})
export class EmailValidatorDirective implements Validator {
    constructor(private _http: HttpService) {}

    validate(
        c: AbstractControl
    ): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
        return this.validateEmail(c.value);
    }

    private validateEmail(email: String): Observable<ValidationErrors | null> {
        return this._http.post('user/validate-email', { email }).pipe(
            debounceTime(500),
            distinctUntilChanged(),
            map((isUsed) => {
                // null no error, object for error
                return !isUsed
                    ? null
                    : {
                            isTaken: 'Email exists already.'
                      };
            })
        );
    }
}

Template:

<input
    id="email"
    type="email"
    class="form-control"
    formControlName="email"
    emailValidator
    placeholder="Enter E-mail Address"
/>

// always showing null
{{ formcontrol['email'].errors | json }}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

≈。彩虹 2025-02-17 13:51:32

您需要实施 asycnvalidator

如果您愿意,您也可以在同一验证器中包含验证器。

private validateEmail(email: string): Observable<ValidationErrors | null> {
    //required
    if (!email) return of({ required: true });

    //email regExpr
    const EMAIL_REGEXP =
      /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;

    if (!EMAIL_REGEXP.test(email)) return of({ email: true });

    return of(email).pipe(
      debounceTime(500),
      distinctUntilChanged(),
      delay(500),
      map((email) => {
        //check if exist
        return emailsYetGet.find((x) => x == email)
          ? {
              isTaken: 'Email exists already.',
            }
          : null;
      })
    );
  }

​stackblitz

注意:请记住,请记住您的指示在模块的声明中,您使用它的组件在哪里,并检查您的api

note2:regexpr我得到了

You need implements AsycnValidator not Validator

If you want, you can also include in the same validator a validator.required and a validator.email

private validateEmail(email: string): Observable<ValidationErrors | null> {
    //required
    if (!email) return of({ required: true });

    //email regExpr
    const EMAIL_REGEXP =
      /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;

    if (!EMAIL_REGEXP.test(email)) return of({ email: true });

    return of(email).pipe(
      debounceTime(500),
      distinctUntilChanged(),
      delay(500),
      map((email) => {
        //check if exist
        return emailsYetGet.find((x) => x == email)
          ? {
              isTaken: 'Email exists already.',
            }
          : null;
      })
    );
  }

a stackblitz

NOTE: Remember include your directive in declarations of the modules where is the components in witch you use it and check you API

NOTE2: the REGEXPR I get it form the Angular's github about validators

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文