繁体   English   中英

Angular 来自 Laravel 后端的 Formbuilder 验证

[英]Angular Formbuilder validation from Laravel Backend

我是 Angular 的新手,目前我正在努力在我的表单字段上显示源自我的 API 后端的错误。 我的前端验证工作没有任何问题。

我已经根据链接设置了前端验证。

这是我的表格 HTML:

<form [formGroup]="createDetailsForm" (ngSubmit)="onCreate()" autocomplete="off" *ngIf="!created_customer">
    <div class="modal-header">
        <h5 class="modal-title">
            {{'create_customer' | transloco | ucfirst}}
        </h5>
        <button type="button" class="close" (click)="d('Cross click')">&times;</button>
    </div>
    <div class="modal-body">
        <div class="form-row">
            <div class="form-group col">
                <label class="form-label">{{'name' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" formControlName="name">
                <app-control-messages [control]="createDetailsForm.get('name')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col mb-0">
                <label class="form-label">{{'vatnumber_prefix' | transloco | ucfirst}}</label>
                <app-countries controlName="vatnumber_prefix"></app-countries>
                <app-control-messages [control]="createDetailsForm.get('vatnumber_prefix')"></app-control-messages>
            </div>
            <div class="form-group col mb-0">
                <label class="form-label">{{'vatnumber' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="xxxxxxxxxx" formControlName="vatnumber"
                    pattern="[0-9]*">
                <app-control-messages [control]="createDetailsForm.get('vatnumber')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col mb-0">
                <label class="form-label">{{'street' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="" formControlName="street">
                <app-control-messages [control]="createDetailsForm.get('street')"></app-control-messages>
            </div>
            <div class="form-group col mb-0">
                <label class="form-label">{{'number' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="" formControlName="number">
                <app-control-messages [control]="createDetailsForm.get('number')"></app-control-messages>
            </div>
            <div class="form-group col mb-0">
                <label class="form-label">{{'suffix' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="" formControlName="suffix">
                <app-control-messages [control]="createDetailsForm.get('suffix')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col mb-0">
                <label class="form-label">{{'zipcode' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="" formControlName="zipcode">
                <app-control-messages [control]="createDetailsForm.get('zipcode')"></app-control-messages>
            </div>
            <div class="form-group col mb-0">
                <label class="form-label">{{'city' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" placeholder="" formControlName="city">
                <app-control-messages [control]="createDetailsForm.get('city')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col">
                <label class="form-label">{{'country' | transloco | ucfirst}}</label>
                <app-countries controlName="country"></app-countries>
                <app-control-messages [control]="createDetailsForm.get('country')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col">
                <label class="form-label">{{'email' | transloco | ucfirst}}</label>
                <input type="email" class="form-control" formControlName="email">
                <app-control-messages [control]="createDetailsForm.get('email')"></app-control-messages>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col">
                <label class="form-label">{{'phone' | transloco | ucfirst}}</label>
                <input type="text" class="form-control" formControlName="phone">
                <app-control-messages [control]="createDetailsForm.get('phone')"></app-control-messages>
            </div>
        </div>

    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-default"
            (click)="c('Close click')">{{'close' | transloco | ucfirst}}</button>
        <button type="submit" class="btn btn-primary">{{'save' | transloco | ucfirst}}</button>

    </div>
</form>

因此,消息与 app-control-messages 组件一起显示。 这与上一个链接中的设置完全相同。 他使用默认验证器和自定义验证服务。 表单组设置如下:

this.createDetailsForm = this.fb.group({
  name: ['', Validators.required],
  vatnumber_prefix: ['BE', Validators.required],
  vatnumber: ['', Validators.compose([Validators.required, ValidationService.numeric])],
  street: ['', Validators.required],
  number: ['', Validators.required],
  suffix: [''],
  zipcode: ['', Validators.required],
  city: ['', Validators.required],
  country: ['BE', Validators.required],
  email: ['', Validators.compose([Validators.required, ValidationService.emailValidator])],
  phone: ['', Validators.required],
  full_vatnumber: [],
});

现在问题出在下面。 我创建了一个服务,我可以从 http 发布到后端的每个错误中调用该服务。 以下是 httpclient 错误响应的示例:

    this.subs.sink = this.custService.createCustomer(value).subscribe((res) => {
  this.custService.add(res);
},
  (error) => {
    this.serverValidation.validate(error, this.createDetailsForm);
  })

这是我接收并发送到验证 function 的错误包。

验证 function:

@Input() form: FormGroup;
@Input() error: HttpErrorResponse;
constructor(private notificationService: NotificationsService) {
}

validate(error, form) {
 if (error.status === 422) {
   form.markAsUntouched();
   form.markAsPristine();
   for (var e in error.error.errors) {
     let control = form.get(e);
     if (control) {
       control.markAsTouched();
       control.markAsDirty();
       control.setErrors({ 'test': true });
       control.updateValueAndValidity();
     } else {
       return undefined;
     }
   }

   form.updateValueAndValidity();
 }

 this.notificationService.error(error.statusText, error.error.message);
}

所以我试图将错误包的内容设置为特定的表单控件,但它没有显示消息。 有人知道我做错了什么吗?

编辑:

正如 Ausiàs Armesto 所建议的,我将代码放在前端组件的错误 function 中:

(error) => {
    console.log(error);
    /* TODO Translate Backend validation errors  to form fields */
    this.createDetailsForm.markAsUntouched();
    this.createDetailsForm.markAsPristine();
    for (var e in error.error.errors) {
      let control = this.createDetailsForm.get(e);
      if (control) {
        control.markAsTouched();
        control.markAsDirty();
        for (var message in error.error.errors[e]) {
          control.setErrors({ 'error': { message: message } })
        }
      } else {
        return undefined;
      }
    }

并更改了我的验证服务以显示“错误”键的消息。 现在消息显示。 所以我的下一个问题是:如何将其重构为外部服务?

解决方案

在错误回调中,我调用了我的服务:

      (error) => {
    this.serverValidation.validate(error, this.createDetailsForm);
  })

验证服务:

export class ServersideFormValidationService {
@Input() form: FormGroup;
@Input() error: HttpErrorResponse;
constructor(private notificationService: NotificationsService) {

}

  validate(error, form) {

    if (error.status === 422) {
      form.markAsUntouched();
      form.markAsPristine();
      for (var e in error.error.errors) {
        let control = form.get(e);
        if (control) {
          control.markAsTouched();
          control.markAsDirty();
          control.setErrors({ 'error': { message: error.error.errors[e][0] } })
        } else {
          return undefined;
        }
      }
    }

    this.notificationService.error(error.statusText, error.error.message);
    }
  }

当表单控件属性位于前端组件(名为“ createDetailsForm ”时)以及位于验证 function 中(名为“ form ”时)时,我会尝试调试它们。 如果不进行彻底测试,表单 object 似乎是重复的,然后在验证function 中所做的更改不会传播到可视组件中定义的表单。 我还会尝试更改验证function 的签名,以便它返回不正确的字段,如下所示:

return ['field1', 'field2']

并在错误处理程序中尝试更新原始表单控件:

(error) => {
    this.serverValidation.validate(error, this.createDetailsForm).forEach(errorControl => {
    this.createDetailsForm.get(errorControl).setErrors = ({ 'test': true })
    })
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM