Angular 使用异步服务进行自定义验证
Angular custom validation with async service
我正在使用 Angular 和 Firestore 数据库(使用 Angularfire2)。为了检查用户名是否已经存在,我使用验证函数进行了自定义验证 class。不幸的是,无论验证函数 returns null 还是 { emailTaken: true },表单似乎都无效。如果我将函数重写为仅 return null 它会起作用,所以我想错误位于此函数中 - 也许它与异步有关?
名称验证器class:
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 }) )
);
}
我正在使用 Angular 和 Firestore 数据库(使用 Angularfire2)。为了检查用户名是否已经存在,我使用验证函数进行了自定义验证 class。不幸的是,无论验证函数 returns null 还是 { emailTaken: true },表单似乎都无效。如果我将函数重写为仅 return null 它会起作用,所以我想错误位于此函数中 - 也许它与异步有关?
名称验证器class:
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 }) )
);
}