问题描述
使用 Angular 12 我有一个带有客户端和服务器验证的简单示例表单。
表单按预期工作,但我不确定我的实施是否是最佳选择。
组件的 HTML
<form [formGroup]="form">
<label for="email">Email</label>
<input id="email" type="text" formControlName="email">
<span class="error" *ngIf="form.get('email')?.invalid && form.get('email')?.touched">
{{form.get('email')?.errors?.incorrect}}
<ng-container *ngIf="form.get('email')?.errors?.required">Email required</ng-container>
<ng-container *ngIf="form.get('email')?.errors?.email">Invalid email</ng-container>
</span>
<button type="submit" (click)="send()" [disabled]="submitted">Send</button>
</form>
组件的打字稿
export class Component implements OnInit {
form: FormGroup;
submitted: boolean;
constructor(private service: Service) {
this.form = this.formBuilder.group({
email: ['',[Validators.required,Validators.email]],});
this.submitted = false;
}
send() {
this.submitted = true;
this.form.markAllAsTouched();
if (this.form.valid) {
this.service.send({email: this.form.value.email}).subscribe(
(next: Payload<Response>) => {
console.log("SUCCESS");
},(error) => {
if (error.status === 400)
new FormGroupErrorBuilder(this.form).setErrors(error.errors);
this.submitted = false;
}
);
} else {
this.submitted = false;
}
}
}
FormGroupErrorBuilder
This is how I am adding server errors to Angular's FormGroup:
export class FormGroupErrorBuilder {
formGroup: FormGroup;
constructor(formGroup: FormGroup) {
this.formGroup = formGroup;
}
setErrors(errors: Error[]) {
for (let error of errors) {
var control = this.formGroup.get(error.name);
if (control)
control.setErrors({ incorrect: error.message });
}
}
}
问题
-
在首次提交时使用
this.form.markAllAsTouched();
对所有表单字段进行验证是否可以接受? -
使用条件
*ngIf="form.get('email')?.invalid && form.get('email')?.touched"
是显示表单域错误的好选择吗?
欢迎任何改进代码的建议......
注意:
我使用 submitted
变量来控制提交按钮是否被禁用并更改其 CSS 样式。
解决方法
查看异步自定义验证器 in the docs:
如果您使用选项 {updateOption:'submit'} 创建您的 formGroup,我认为您可以通过其他方式实现
有些像:例如(我把validator放在FormGroup里,你可以放在自己的控件Email里)——那你应该改一下“validateEmail”函数。
this.form = this.formBuilder.group({
email: ['',[Validators.required,Validators.email]],},{updateOption:'submit',asyncValidator:this.validateEmail()});
validateEmail(): AsyncValidatorFn {
return (group: FormGroup): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return
this.service.send({email:group.value.email}).map(res=>{
if (res.success)
return null
return { repeat: "name yet register" }
})
)))
};
}
注意:当您订阅该服务时,我在您的代码中没有看到清楚。您“捕获”了错误,通常 API 会返回类似 {success:true}
或 {error:'the email is yet!'}
的内容,但如果调用中没有错误,则不要返回状态 400 - 您的 API 可以响应类似以上,但您收到了成功的响应,而不是错误。