我创建了一个自定义验证程序,以在保存新用户之前检查数据库中是否存在电子邮件,但它似乎不起作用。
我的模板
<form class="forms-sample" #f="ngForm" (ngSubmit)="onSaveUser(f.value)">
<input type="email" class="form-control" id="email" ngModel name="email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" #email="ngModel" placeholder="Email" emailValidator>
<div *ngIf="email?.errors.emailValidator">This email has been taken, please use another one.</div>
.......................................................
<button class="btn btn-md-12 btn-outline-primary btn-fw btn-icon-text clickable" [disabled]="f.invalid || userFile==null" type="submit">
</form>
我的验证人
import { NG_VALIDATORS, FormControl, ValidatorFn, Validator } from '@angular/forms';
import { Directive } from '@angular/core';
import {UsersService} from '../../services/users.service';
@Directive({
selector: '[emailValidator][ngModel]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: EmailValidator,
multi: true
}
]
})
export class EmailValidator implements Validator {
validator: ValidatorFn;
constructor(public usersService:UsersService) {
this.validator = this.emailValidator("");
}
validate(c: FormControl) {
return this.validator(c);
}
emailValidator(email:string): ValidatorFn {
return (c: FormControl) => {
this.usersService.checkEmailTaken(email)
.subscribe((res)=>{
let isValid = res;
if (isValid==null) {
return true;
}
});
return {
emailValidator: {
valid: false
}
};
}
}
}
我的服务返回用户(如果存在),否则返回null。
checkEmailTaken(email: string) {
if(this.jwtToken==null) this.authenticationService.loadToken();
return this.http.get(this.host+"/checkEmailTaken?email="+email
, {headers:new HttpHeaders({'Authorization':this.jwtToken})}
);
}
该服务运行良好,但是我不知道为什么自定义验证似乎不起作用?
答案 0 :(得分:0)
服务
getUserByEmail(email:string){
if(this.jwtToken==null) this.jwtToken = this.authenticationService.loadToken();
return this.http.get(this.host+"/userByEmail?email="+email
, {headers:new HttpHeaders({'Authorization':this.jwtToken})}
);
}
验证器
import { Directive } from '@angular/core';
import { AsyncValidator, AbstractControl, ValidationErrors, NG_ASYNC_VALIDATORS, AsyncValidatorFn } from '@angular/forms';
import { map } from 'rxjs/operators';
import {UsersService} from '../../services/users.service';
export function uniqueUserEmailValidator(usersService: UsersService): AsyncValidatorFn {
return (c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return usersService.getUserByEmail(c.value)
.map(data=> {
return data ? { 'uniqueUserEmail': true } : null;
});
};
}
@Directive({
selector : '[uniqueUserEmail][ngModel]',
providers : [{ provide: NG_ASYNC_VALIDATORS, useExisting:UniqueUserEmailValidator, multi:true}]
})
export class UniqueUserEmailValidator implements AsyncValidator {
constructor(private usersService: UsersService) {}
validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return uniqueUserEmailValidator(this.usersService)(c);
}
}
app.module.ts 我们必须在声明中添加验证器,以便可以在表单中使用它。
@NgModule({
declarations: [UniqueUserEmailValidator]
})
模板
<input type="email" class="form-control" id="email" ngModel name="email" required uniqueUserEmail pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" #email="ngModel" placeholder="Email">
<div *ngIf="email?.errors.uniqueUserEmail">This email has been taken, please use a different one.</div>