Sté*_*ane 7 validation asynchronous angular
我编写了一个异步验证器来检查输入的电子邮件是否已存在于我的数据库中。
\n\n我使用反应式表单 api 来构建我的表单,并将异步验证器配置为仅在“模糊”时触发。正如角度文档中提到的
\n\n它运行良好:当我离开该字段时会触发验证,但直到我与表单交互时才会显示错误消息。
\n\n如果我在验证中使用 setTimeout 函数手动触发changeDetection,它就会起作用。
\n\n知道为什么验证完成后不直接显示此错误吗?
\n\n这是我的表单定义:
\n\nprivate initPersonalInformationFormGroup() {\n this.personalInformationFormGroup = this._formBuilder.group({\n lastName: [\'\', Validators.required],\n firstName: [\'\', Validators.required],\n gender: [Gender.MALE],\n birthDate: [\'\'],\n birthPlace: [\'\'],\n nationality: [\'\'],\n inss: [\'\', [Validators.minLength(11), Validators.maxLength(11), Validators.pattern(\'[0-9]{11}\')]],\n email: [\'\', {\n validators: [Validators.required, Validators.email],\n asyncValidators: [this._studentEmailValidator()],\n updateOn: \'blur\'\n }],\n phoneNumber: [null, Validators.pattern(\'\\\\+32[1-9][0-9]{7,8}\')],\n address: this._formBuilder.group({\n street: [\'\', [Validators.maxLength(60)]],\n houseNumber: [\'\', [Validators.maxLength(10)]],\n city: [\'\', [Validators.maxLength(60)]],\n postalCode: [null, [Validators.min(1000), Validators.max(9999)]],\n }, {\n validators: this._completeAddressValidator()\n }),\n previousSchool: [\'\', Validators.maxLength(60)],\n additionalInformation: [\'\']\n })\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我的验证方法:
\n\nprivate _studentEmailValidator(): AsyncValidatorFn {\n return (control: FormGroup): Observable<{ [key: string]: any } | null> => {\n const email = control.value;\n // setTimeout(() => this._checkDetectorRef.detectChanges(), 5000);\n return this._adminFacade.checkStudentWithEmailExists(email).pipe(\n take(1),\n map(exists => exists ? {\'emailAlreadyUserByStudent\': {value: email}} : null),\n catchError(() => null)\n );\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n\n以及模板的部分:
\n\n<mat-form-field fxFlex="60">\n <mat-placeholder>\n <mat-icon>email</mat-icon>\n <span> Email</span>\n </mat-placeholder>\n <input matInput formControlName="email">\n <mat-error *ngIf="email.hasError(\'emailAlreadyUserByStudent\')">\n Email d\xc3\xa9j\xc3\xa0 utilis\xc3\xa9.\n </mat-error>\n <span *ngIf="email.pending">Validating...</span>\n</mat-form-field>\nRun Code Online (Sandbox Code Playgroud)\n
作为一种解决方法(我仍然不确定这是最好的方法,因为在代码示例中没有必要......),我在验证器函数的末尾添加了一个手动 detectorChanges :
private _studentEmailValidator(): AsyncValidatorFn {
return (control: FormGroup): Observable<{ [key: string]: any } | null> => {
const email = control.value;
return this._adminFacade.checkStudentWithEmailExists(email).pipe(
take(1),
map(exists => exists ? {'emailAlreadyUserByStudent': {value: email}} : null),
catchError(() => null),
tap(() => setTimeout(() => this._checkDetectorRef.detectChanges(), 0))
);
}
Run Code Online (Sandbox Code Playgroud)
};
Lea*_*ima -1
尝试这样做:
import { ChangeDetectorRef } from '@angular/core';
constructor(
changeDetectorRef: ChangeDetectorRef
) {
//call this when you receive the backend response
changeDetectorRef.markForCheck();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4673 次 |
| 最近记录: |