Angular 使用“订阅”设置自定义验证错误

Angular 使用“订阅”设置自定义验证错误,angular,subscription,form-control,Angular,Subscription,Form Control,我希望根据数据库中的数据设置验证错误 具有自定义验证程序功能的Formcontrol: nUname: ['', [Validators.required,unique_uname]] 自定义验证程序功能: nUname: ['', [Validators.required,unique_uname]] 下面的函数获取用户名,并在服务中使用post请求获取数据。如果用户名在数据库服务返回响应中,状态为“S”,否则错误状态为“F” 如果状态为“S”,则应将错误“uname_repeat”设置为

我希望根据数据库中的数据设置验证错误

具有自定义验证程序功能的Formcontrol:

nUname: ['', [Validators.required,unique_uname]]
自定义验证程序功能:

nUname: ['', [Validators.required,unique_uname]]
下面的函数获取用户名,并在服务中使用post请求获取数据。如果用户名在数据库服务返回响应中,状态为“S”,否则错误状态为“F”

如果状态为“S”,则应将错误“uname_repeat”设置为formcontrol。uname_repeat error不是在subscribe中设置的,而是在subscribe外部设置的,它可以根据需要工作

function unique_uname(){
  return (control: AbstractControl): {[key: string]:any} | null => {
    const uname = control.value;
    if(uname.length!=0){
      ser.get_user(uname).subscribe(
        (res) => {
          if (res['status']=='S') {
             return {'uname_repeat':true} <-- This is not working
          }
        },
        (err) => {
          if (err['error']['status']=='F') {
            return null;
          }
        }

        );
        return {'uname_repeat':true} <-- This working

      }
      return null;
    };
  }
function unique\u uname(){
return(control:AbstractControl):{[key:string]:any}| null=>{
const uname=control.value;
如果(取消指定长度!=0){
服务获取用户(uname)。订阅(
(res)=>{
如果(res['status']='S'){
返回{'uname_repeat':true}{
如果(错误['error']['status']='F'){
返回null;
}
}
);

return{'uname_repeat':true}这里需要使用的是

有两种方法可以以反应式形式使用
异步验证器

validateEmailNotTaken(control: AbstractControl) {
    return this.signupService.checkEmailNotTaken(control.value).pipe(
        map(res => {
            return res ? null : { emailTaken: true };
        })
    );
}
首先,您可以在组件中添加验证函数,并将其包含在反应式表单中

validateEmailNotTaken(control: AbstractControl) {
    return this.signupService.checkEmailNotTaken(control.value).pipe(
        map(res => {
            return res ? null : { emailTaken: true };
        })
    );
}
并以如下形式包括:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        this.validateEmailNotTaken.bind(this)
    ]
});
this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        ValidateEmailNotTaken.createValidator(this.signupService)
    ]
});
或者,您可以创建一个单独的验证文件

export class ValidateEmailNotTaken {
    static createValidator(signupService: SignupService) {
        return (control: AbstractControl) => {
            return signupService.checkEmailNotTaken(control.value).pipe(
                map(res => {
                    return res ? null : { emailTaken: true };
                })
            );
        };
    }
}
并以如下形式包括:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        this.validateEmailNotTaken.bind(this)
    ]
});
this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        ValidateEmailNotTaken.createValidator(this.signupService)
    ]
});

这里有一个stackblitz供参考。

您需要在这里使用的是

有两种方法可以以反应式形式使用
异步验证器

validateEmailNotTaken(control: AbstractControl) {
    return this.signupService.checkEmailNotTaken(control.value).pipe(
        map(res => {
            return res ? null : { emailTaken: true };
        })
    );
}
首先,您可以在组件中添加验证函数,并将其包含在反应式表单中

validateEmailNotTaken(control: AbstractControl) {
    return this.signupService.checkEmailNotTaken(control.value).pipe(
        map(res => {
            return res ? null : { emailTaken: true };
        })
    );
}
并以如下形式包括:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        this.validateEmailNotTaken.bind(this)
    ]
});
this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        ValidateEmailNotTaken.createValidator(this.signupService)
    ]
});
或者,您可以创建一个单独的验证文件

export class ValidateEmailNotTaken {
    static createValidator(signupService: SignupService) {
        return (control: AbstractControl) => {
            return signupService.checkEmailNotTaken(control.value).pipe(
                map(res => {
                    return res ? null : { emailTaken: true };
                })
            );
        };
    }
}
并以如下形式包括:

this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        this.validateEmailNotTaken.bind(this)
    ]
});
this.myForm = this.fb.group({
    name: ['', Validators.required],
    email: [
        '',
        [Validators.required, Validators.email],
        ValidateEmailNotTaken.createValidator(this.signupService)
    ]
});

这里有一个stackblitz供参考。

您尝试过异步验证程序吗?您尝试过异步验证程序吗?