【问题标题】:Display Client Errors and then Server Errors on Angular's Reactive Form after submission提交后在 Angular 的响应式表单上显示客户端错误和服务器错误
【发布时间】:2021-10-05 07:36:49
【问题描述】:

使用 Angular 12 我有一个带有客户端和服务器验证的简单示例表单。

  1. 我只想在第一次提交表单后显示客户端验证错误;

  2. 客户端验证成功后,我会显示服务器验证错误。

    服务器验证错误在表单字段错误中添加为“不正确”字段。

  3. 我正在使用响应式表单。

表单按预期工作,但我不确定我的实现是否是最佳选择。

组件的 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 });
        
    }

  } 

} 

问题

  1. 是否可以在首次提交时使用this.form.markAllAsTouched(); 对所有表单字段进行验证?

  2. 使用条件*ngIf="form.get('email')?.invalid &amp;&amp; form.get('email')?.touched" 是显示表单字段错误的好选择吗?

欢迎任何改进代码的建议...

注意:

我正在使用submitted 变量来控制提交按钮是否被禁用并更改其 CSS 样式。

【问题讨论】:

    标签: angular angular-reactive-forms angular2-forms


    【解决方案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=&gt;{success:false})
    猜你喜欢
    • 2020-07-27
    • 1970-01-01
    • 2017-10-26
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多