[英]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.