Javascript 使用异步服务进行角度自定义验证

Javascript 使用异步服务进行角度自定义验证,javascript,angular,firebase,google-cloud-firestore,angularfire2,Javascript,Angular,Firebase,Google Cloud Firestore,Angularfire2,我正在使用Angularfire2和Firestore数据库。为了检查用户名是否已经存在,我创建了一个带有validate函数的自定义验证类。不幸的是,不管validate函数返回null或{emailtake:true},表单似乎都是无效的。如果我重写函数只返回null,那么它就可以工作,所以我假设错误位于这个函数中——可能与它是异步的有关 NameValidator类: import { FirebaseService } from './../services/firebase.servi

我正在使用Angularfire2和Firestore数据库。为了检查用户名是否已经存在,我创建了一个带有validate函数的自定义验证类。不幸的是,不管validate函数返回null或{emailtake:true},表单似乎都是无效的。如果我重写函数只返回null,那么它就可以工作,所以我假设错误位于这个函数中——可能与它是异步的有关

NameValidator类:

import { FirebaseService } from './../services/firebase.service';
import { FormControl } from "@angular/forms";
import { Injectable } from '@angular/core';

@Injectable()
export class NameValidator {
  constructor(private firebaseService: FirebaseService) { }

  validate(control: FormControl): any {
    return this.firebaseService.queryByUniqueNameOnce(control.value).subscribe(res => {
        return res.length == 0 ? null : { emailTaken: true };
    });
  }
}
firebaseService查询功能:

queryByUniqueNameOnce(uniqueName: string) {
 return this.firestore.collection("users", ref => ref.where('uniqueName', '==', uniqueName))
 .valueChanges().pipe(take(1));
}
表格组:

 this.firstForm = this.fb.group({
  'uniqueName': ['', Validators.compose([Validators.required, this.nameValidator.validate.bind(this.nameValidator)])],
});

异步验证器是表单控件的第三个参数

此外,
compose
在最新版本中变得无用

'uniqueName': ['', [/*sync validators*/], [this.nameValidator.validate]]
您还必须更改验证功能:

  validate(control: FormControl): any {
    return this.firebaseService.queryByUniqueNameOnce(control.value).pipe(
      map(res => !res.length ? null : ({ emailTaken: true }) )
    );
  }