Angular 中的异步验证器无法使用模板驱动的表单
Async Validator not working with Template driven Forms in Angular
我已经为我的模板驱动表单创建了一个异步验证器。
import {Directive, forwardRef} from "@angular/core";
import {NG_ASYNC_VALIDATORS, Validator, AbstractControl, AsyncValidator} from "@angular/forms";
import {Observable} from "rxjs";
@Directive({
selector: '[asyncValidator][ngModel]',
providers: [{
provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => AsyncAgeValidator), multi: true
}]
})
export class AsyncAgeValidator implements Validator{
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value);
}
validateAgeObservable( age: number ) {
return new Observable(observer => {
if( age === 20 ) {
observer.next(null);
} else {
observer.next({asyncInvalid: true});
console.log('validate');
}
});
}
}
}
我正在我的模板中使用它,如下所示,但我没有从模板中的验证程序中收到我期望的错误消息。调用将转到验证器,但我猜它没有在组件中注册可观察对象。
<md-input-container>
<input mdInput type="number" name="age" [(ngModel)]="user.age" placeholder="Age" required asyncValidator>
</md-input-container>
您的 observable 永远不会完成,因此 Angular 不知道何时更改表单状态。所以请记住您的可观察对象必须完成。
您可以通过多种方式完成此操作:
1) 手动调用观察者的 complete()
方法:
validateAgeObservable( age: number ) {
return new Observable(observer => {
observer.next(age === 20 ? null : {asyncInvalid: true});
observer.complete();
});
}
2) 调用first()
方法:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).first();
}
validateAgeObservable( age: number ) {
return new Observable(observer => {
observer.next(age === 20 ? null : {asyncInvalid: true});
});
}
添加到yurzui的第二个回答:
这个有效:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).first();
}
也是这样:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).take(1);
}
我已经为我的模板驱动表单创建了一个异步验证器。
import {Directive, forwardRef} from "@angular/core";
import {NG_ASYNC_VALIDATORS, Validator, AbstractControl, AsyncValidator} from "@angular/forms";
import {Observable} from "rxjs";
@Directive({
selector: '[asyncValidator][ngModel]',
providers: [{
provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => AsyncAgeValidator), multi: true
}]
})
export class AsyncAgeValidator implements Validator{
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value);
}
validateAgeObservable( age: number ) {
return new Observable(observer => {
if( age === 20 ) {
observer.next(null);
} else {
observer.next({asyncInvalid: true});
console.log('validate');
}
});
}
}
}
我正在我的模板中使用它,如下所示,但我没有从模板中的验证程序中收到我期望的错误消息。调用将转到验证器,但我猜它没有在组件中注册可观察对象。
<md-input-container>
<input mdInput type="number" name="age" [(ngModel)]="user.age" placeholder="Age" required asyncValidator>
</md-input-container>
您的 observable 永远不会完成,因此 Angular 不知道何时更改表单状态。所以请记住您的可观察对象必须完成。
您可以通过多种方式完成此操作:
1) 手动调用观察者的 complete()
方法:
validateAgeObservable( age: number ) {
return new Observable(observer => {
observer.next(age === 20 ? null : {asyncInvalid: true});
observer.complete();
});
}
2) 调用first()
方法:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).first();
}
validateAgeObservable( age: number ) {
return new Observable(observer => {
observer.next(age === 20 ? null : {asyncInvalid: true});
});
}
添加到yurzui的第二个回答:
这个有效:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).first();
}
也是这样:
validate(c: AbstractControl): Observable<{[key : number] : any}>{
return this.validateAgeObservable(c.value).take(1);
}