[英]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')">×</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:
@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.