1

我有一个问题,我没有得到角度反应形式的异步验证。在编写有关输入时,我可以保持查询处于活动状态,它会给我带来结果,但我无法在 html 中发送错误。我是角度方面的新手,我不知道我会在代码中遗漏什么。

组件.ts

  this.registroForm = this.fb.group({
  nombre: ["", [Validators.required, Validators.pattern("[a-zA-Z ]*")]],
  apellido: ["", [Validators.required, Validators.pattern("[a-zA-Z ]*")]],
  username: [
    "",
    [Validators.required, this.validateEmailNotTaken.bind(this)]
  ],
  email: ["", [Validators.required, Validators.pattern(this.emailPattern)]],
  telefono1: [
    "",
    [
      Validators.required,
      Validators.maxLength(10),
      Validators.minLength(10),
      Validators.pattern("[0-9]*")
    ]
  ],
  condiciones: ["", [Validators.required]]
});

我的验证功能:每次我在输入中写入时都会检查,服务器以下列方式响应我,当名称存在于 BD 中时,它会将它的数据带到 json 数组中,但是一个空数组,这就是为什么数据长度。因此,如果它等于 1,它应该显示错误。但是输入写了任何东西,它被放置为红色,没有显示特定的错误(用于验证材料角度),除了它不显示它是否存在或名称不可用的错误。

  validateEmailNotTaken(control: AbstractControl) {
let username = {
  user: control.value
};
return this.authService.buscarUserUsername(username).subscribe(
  (data: any) => {
    console.log(data.length);
    if (data.length === 1) {
      return { userNameExists: true };
    }
  },
  err => {
    console.log(err);
  }
);

HTML

<mat-form-field appearance="outline" color="accent">
           <mat-label>Usuario</mat-label>
           <input formControlName="username" matInput placeholder="Nombre de usuario">
           <mat-error *ngIf="registroForm.controls['username'].errors?.required">Este campo es obligatorio
           </mat-error>
           <mat-error *ngIf="registroForm.controls['username'].errors?.pattern">No es un nombre de usuario valido
           </mat-error>
           <mat-error *ngIf="registroForm.get('username').errors?.userNameExists">
             Nombre de usuario no disponible               </mat-error>

         </mat-form-field>
4

1 回答 1

1

问题是您试图从内部返回值subscribe()。相反,您应该返回一个Observable<ValidationErrors | null>带有此异步验证器的映射响应。这可以通过使用诸如mapcatchError 之类的管道运算符来实现:

validateEmailNotTaken(control: AbstractControl) {
  let username = {
    user: control.value
  };

  return this.authService.buscarUserUsername(username).pipe(
    map(data => {
      if (data.length === 1) {
        // return error
        return {
          userNameExists: true
        };
      }

      // return null for no errors
      return null;
    }),
    catchError(err => {
      // handle error
      console.log(err);
    })
  )
}

作为一般规则,请仔细查看 Angular 类/接口的返回类型。在任何地方您看到的返回类型Observable<T>都可能无法使用subscribe(),而是需要使用可管道操作符。

同样如评论中所建议的,请确保将验证器属性传递给表单配置:

username: ["", Validators.required, this.validateEmailNotTaken.bind(this)]

希望这会有所帮助!

于 2019-09-16T21:28:24.890 回答