簡體   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