我正在尝试做一个自定义的异步验证器,它检查所提供的电子邮件是否已经存在于DB上。当出现错误时,它可以正常工作,但当错误得到解决(输入有效数据)时,它将显示Cannot read property 'emailIsTaken' of null
我用的是模板驱动的方法。我就是这样用的。
<input type="email" name="email" [(ngModel)]='email' #mail='ngModel' required [pattern]='emailPattern' validateEmail>使用错误码
<div *ngIf='mail.errors["emailIsTaken"]'>Email already Registered!</div>这是我的验证器文件
import { Validator, AbstractControl, NG_ASYNC_VALIDATORS } from '@angular/forms';
import { Directive, Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Directive({
selector: '[validateEmail]',
providers: [{
provide: NG_ASYNC_VALIDATORS,
useExisting: EmailValidator,
multi: true
}]
})
@Injectable()
export class EmailValidator implements Validator {
constructor(private http: HttpClient){}
validate(control: AbstractControl): Promise<any> | Observable<any> {
return new Promise(resolve => {
this.http.get('http://surjit.com/email.php?q=' + control.value).subscribe((success)=>{
if(success === true){
resolve(null);
}
else{
resolve({'emailIsTaken': true});
}
});
});
}
}当我使用内置的email验证器时,也会发生相同的错误。
发布于 2018-03-23 10:44:22
如果您想要执行这个异步,那么您需要实现AsyncValidator。
另外,您还需要返回可观察到的结果,而不是订阅它。这里做的最简单的事情是使用可观察的而不是承诺,但是您也可以在.map()之后链接.map()。您不想在这里订阅,您希望返回可观察到的本身(或承诺),但是您确实希望这个承诺返回预期的结果,这就是为什么您应该使用map。
另外,如果您还没有这样做,我建议您切换到使用pipable操作符。另见map。
import { AsyncValidator } from '@angular/forms';
import { map } from 'rxjs/operators/map';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class EmailValidator implements AsyncValidator {
constructor(private http: HttpClient){}
validate(control: AbstractControl): Promise<any> | Observable<any> {
return this.http.get('http://surjit.com/email.php?q=' + control.value)
.pipe(map((success)=> success ? null : {'emailIsTaken': true}));
}
}上面的只是修改过的EmailValidator类。
参见我根据上面的.创建的 StackBlitz
编辑
根据错误屏幕截图,最有可能的原因是您在HTML中检查了应该根据结果验证显示哪些错误,这没有考虑到如果没有错误,验证结果是null这一事实。最简单的修复方法是使用安全导航操作员(?)和空属性路径 ?。示例:
<element *ngIf="errResult?.emailIsTaken">Email is in use</element>发布于 2018-03-23 10:35:44
这是你的问题:
if(success === true){
resolve(null);
}如果验证成功,则返回null,而不是使用“emailIsTaken”字段的对象。
关于
if(success === true){
resolve({'emailIsTaken': false});
}如果这符合你的代码呢?
https://stackoverflow.com/questions/49447638
复制相似问题