无法读取未定义的 属性 'userService' - 实现异步验证器 (Angular 12)

Cannot read property 'userService' of undefined - implementing async validator (Angular 12)

最近几天我一直在尝试实施异步验证。但是 tutorials/solutions 中的 none 正在工作!

服务代码-

getUserIdToCheckDuplicate(userId:any):Observable<any>{
    const url = ``; //url goes here
    return this.http.get<any>(url);
  }

组件代码-

ngOnInit(): void {
 this.form = this.fb.group({
      userId: ['', [Validators.required],[this.validate]]})
}
validate(control: AbstractControl): Observable<ValidationErrors | null> {
    console.log(control.value);
    return of(control.value)
      .pipe(
        delay(10),
        switchMap((value) =>
          this.userService.getUserIdToCheckDuplicate(value).pipe(map(x => {
            return x.exists ? { exists: true } : null;
          }))
        )
      );
  }

Html代码-

        <mat-form-field appearance="outline" fxFlex="1 1 calc(25% - 10px)" fxFlex.lt-md="1 1 calc(25% - 10px)"
                    fxFlex.lt-sm="100%" fxFlex.xs="100%" class="from-color" *ngIf="!data">
          <mat-label class="label-padding">User ID</mat-label>
             <input class="label-padding" formControlName="userId" matInput placeholder="User ID" required />
                <div style="color: red; font-weight: bold;" *ngIf="userId.errors?.exists">Already
                      Exists !</div>
     </mat-form-field>

在控制台中- console error

在控制台中,当我在输入中写一些东西时,每个键 storke 它打印值,但在那之后告诉 value 是未定义的!

此错误背后的原因是什么?我该如何解决这个问题?它应该可以正常工作,这样 异步验证器 也能正常工作。

谁能帮我解决这个问题?

我成功重现了下面的错误stackblitz

问题是 this 在这个上下文中不是指 class

一个简单的解决方案是简单地使用箭头函数进行验证

validate = (control: AbstractControl): Observable<ValidationErrors | null> => {
    console.log(control.value);
    return of(control.value)
      .pipe(
        delay(10),
        switchMap((value) =>
          this.userService.getUserIdToCheckDuplicate(value).pipe(map(x => {
            return x.exists ? { exists: true } : null;
          }))
        )
      );
  }

看到这个Here

比这一切都简单:

validate = (
    control: AbstractControl
  ): Observable<ValidationErrors | null> => {
    return this.userService.getUserIdToCheckDuplicate(control.value).pipe(
          map(x => {
            return x? { exists: true } : null;
          })
      
    );

(*)如果没有重复项

,我想您的服务 return 为 null

参见stackblitz(检查,“傻瓜”重复)

如果您正在使用 material

  <mat-form-field class="name" appearance="outline">
    <input matInput placeholder="Name" formControlName="userId">
    <mat-error *ngIf="form.get('userId')?.hasError('required')">
      Name is required*
    </mat-error>
    <mat-error *ngIf="form.get('userId')?.hasError('exists')">
      Name repeat
    </mat-error>
    <mat-hint *ngIf="form.get('userId')?.pending">Validating...</mat-hint>
  </mat-form-field>

但最好检查错误 'onblur'(否则错误不会由缺陷显示:在 material 中,如果我们不使用自定义错误匹配器,则仅在 formControl 时显示错误被触摸(编辑和模糊)

this.form = this.fb.group({
  userId: ['', [Validators.required], [this.validate]]
},{updateOn:'blur'});