【发布时间】:2020-11-02 14:18:58
【问题描述】:
我正在使用一个简单的表单在 Angular 10 中做一个 Web 应用程序来接收两个值,我将在后端验证它们,执行 HTTP 调用。为此,我创建了一个运行完美的异步验证器。
问题: 它没有将错误设置为 FormGroup。换言之,FormGroup 始终有效。
this.form = this.fb.group({
// I will validate this two values with the backend
patientIdentifications: this.fb.group({
clinicRecord: [null, Validators.required],
documentId: [null, Validators.required]
}, {
updateOn: 'blur',
asyncValidators: CustomValidators.isPatientValid(this.myService) // <= async validator
}),
// Just to illustrate that I have more FormControls
firstName: [null, Validators.required],
});
异步验证器
export class CustomValidators {
static isPatientValid(myService: MyService): AsyncValidatorFn {
return (formGroup: FormGroup):
Promise<ValidationErrors | null> |
Observable<ValidationErrors | null> => {
const clinicRecordControl = formGroup.controls.clinicRecord;
const documentIdControl = formGroup.controls.documentId;
const clinicRecordValue = clinicRecordControl.value;
const documentIdValue = documentIdControl.value;
return myService.getPatient(clinicRecordValue, documentIdValue).pipe(
map(patient => patient ? of(null) : of({valid: true})),
catchError(() => of(null))
);
};
}
}
当两个输入失去焦点时,HTTP 调用完美完成。但是FormGroup中没有设置错误。
我尝试了以下解决方案:
#1。在验证器调用中添加bind()
patientIdentifications: this.fb.group({
clinicRecord: [null, Validators.required],
documentId: [null, Validators.required]
}, {
updateOn: 'blur',
asyncValidators: CustomValidators.isPatientValid(this.myService).bind(this) // <= bind
}),
#2。去掉of函数
return myService.getPatient(clinicRecordValue, documentIdValue).pipe(
map(patient => patient ? null : {valid: true}), // <= remove the "of"
catchError(() => of(null))
);
#3。直接使用FormGroup的实例设置错误
return myService.getPatient(clinicRecordValue, documentIdValue).pipe(
map(patient => patient ? formGroup.setErrors(null) : formGroup.setErrors({valid: true})),
catchError(() => of(null))
);
没有一个解决方案对我有用。
我的目标是正确设置 FormGroup 的错误,使 FormGroup 为 INVALID,这是正确的做法。
【问题讨论】:
-
不应该
catchError(() => of(null))返回of({valid: true}),因为这是一个错误? -
也可以尝试将
map换成switchMap。 -
@Chrillewoodz 你的意思是做
return formGroup.valueChanges.pipe(switchMap...还是直接返回switchMap? -
return myService.getPatient(clinicRecordValue, documentIdValue).pipe( switchMap(patient => patient ? of(null) : of({valid: true})), catchError(() => of(null)) ); -
@Chrillewoodz 信不信由你,你的第一条评论解决了我的问题,我需要在
catchError中返回of({valid: true})。此外,它适用于switchMap或map,尽管我不明白其中的区别。我知道switchMap是干什么用的,但从未见过它被这样使用过。最后,我不确定正确的做法是of(null)还是formGroup.setErrors(null)。如果你能用最好的方法给出答案,我会接受。
标签: angular angular-reactive-forms