提交后在 Angular 的响应式表单上显示客户端错误和服务器错误
Posted
技术标签:
【中文标题】提交后在 Angular 的响应式表单上显示客户端错误和服务器错误【英文标题】:Display Client Errors and then Server Errors on Angular's Reactive Form after submission 【发布时间】:2021-10-05 07:36:49 【问题描述】:使用 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 样式。
【问题讨论】:
【参考方案1】:看看异步自定义验证器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 可以像上面一样响应但您收到响应成功,没有错误。
【讨论】:
我正在检查一些 API,当请求格式错误时,其中一些返回 400 错误。例如,当数据不正确时。当验证失败时,其他人似乎返回 HTTP 422 错误而不是 400。其他人按照您所说的进行操作并返回 HTTP 成功代码,但响应中有错误。我不确定哪个更好。 @MiguelMoura,如果你想在 subscribe(next) 中获得所有响应,你可以使用pipe(catchError(err=>success:false)
以上是关于提交后在 Angular 的响应式表单上显示客户端错误和服务器错误的主要内容,如果未能解决你的问题,请参考以下文章