我可以使用 Subject 来制作自定义异步验证器吗?
Can i use a Subject to make a custom async validator?
我是否有机会通过一个主题实现这一目标?目前我只是通过承诺实现了这一点。所以我调用了 resolve 方法,它工作正常。
我正在尝试执行以下操作。
forbiddenEmail(control: FormControl): Observable<any> {
const obs = new Subject();
setTimeout(() => {
if (control.value === 'test@test.com') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
}, 2000);
return obs;
}
在这里,我试图在值为 test@test.com 时发出事件,否则为 null,正如 Angular 中的文档所说的验证器。
我试图模拟让我们说一个后端服务,这就是为什么我实现 setTimeout 功能并给出 2 秒的超时。
现在的问题是,当我检查放置验证器的输入元素(电子邮件输入元素)时,总是显示 class ng-pending
。
所以,出于某种原因我没有订阅它我知道。但我怎么能?
这是我在 FormGroup 中调用验证器的地方。
ngOnInit() {
this.signupForm = new FormGroup({
'userData': new FormGroup({
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmail.bind(this))
}),
'gender': new FormControl('male'),
'hobbies': new FormArray([])
});
}
根据文档,您可以通过返回可观察对象来实现:
https://angular.io/api/forms/AsyncValidatorFn
我试图用代码示例来证明它,但它看起来并没有像它应该的那样工作...
看起来像 angular 问题本身,这里报告:https://github.com/angular/angular/issues/13200
您需要完成您的 observable:
setTimeout(() => {
if (control.value === 'test@test.com') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
obs.complete();
}, 2000);
但这可以用更简单的方式定义:
forbiddenEmail2(control: FormControl): Observable<any> {
const result = control.value === 'test@test.com' ? {'emailIsForbidden': true} : null;
return Observable.of(result).delay(2000);
}
这也更正确,因为它实际上是在调用验证程序时验证输入,而不是在 2 秒后验证输入。在更现实的用例中:您将立即获得输入,并将其发送到后端。
当然,只是 return 带有 asObservable()
的主题:
forbiddenEmail(control: FormControl): Observable<any> {
const subject = new Subject();
setTimeout(() => {
if (control.value === 'test@test.com') {
subject.next({ emailIsForbidden: true });
} else {
subject.next(null);
}
}, 2000);
return subject.asObservable();
}
我是否有机会通过一个主题实现这一目标?目前我只是通过承诺实现了这一点。所以我调用了 resolve 方法,它工作正常。
我正在尝试执行以下操作。
forbiddenEmail(control: FormControl): Observable<any> {
const obs = new Subject();
setTimeout(() => {
if (control.value === 'test@test.com') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
}, 2000);
return obs;
}
在这里,我试图在值为 test@test.com 时发出事件,否则为 null,正如 Angular 中的文档所说的验证器。
我试图模拟让我们说一个后端服务,这就是为什么我实现 setTimeout 功能并给出 2 秒的超时。
现在的问题是,当我检查放置验证器的输入元素(电子邮件输入元素)时,总是显示 class ng-pending
。
所以,出于某种原因我没有订阅它我知道。但我怎么能?
这是我在 FormGroup 中调用验证器的地方。
ngOnInit() {
this.signupForm = new FormGroup({
'userData': new FormGroup({
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmail.bind(this))
}),
'gender': new FormControl('male'),
'hobbies': new FormArray([])
});
}
根据文档,您可以通过返回可观察对象来实现: https://angular.io/api/forms/AsyncValidatorFn
我试图用代码示例来证明它,但它看起来并没有像它应该的那样工作...
看起来像 angular 问题本身,这里报告:https://github.com/angular/angular/issues/13200
您需要完成您的 observable:
setTimeout(() => {
if (control.value === 'test@test.com') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
obs.complete();
}, 2000);
但这可以用更简单的方式定义:
forbiddenEmail2(control: FormControl): Observable<any> {
const result = control.value === 'test@test.com' ? {'emailIsForbidden': true} : null;
return Observable.of(result).delay(2000);
}
这也更正确,因为它实际上是在调用验证程序时验证输入,而不是在 2 秒后验证输入。在更现实的用例中:您将立即获得输入,并将其发送到后端。
当然,只是 return 带有 asObservable()
的主题:
forbiddenEmail(control: FormControl): Observable<any> {
const subject = new Subject();
setTimeout(() => {
if (control.value === 'test@test.com') {
subject.next({ emailIsForbidden: true });
} else {
subject.next(null);
}
}, 2000);
return subject.asObservable();
}