[英]Automatically populate errors for reactive form controls in Angular 2/4
我在前端和后端都进行了验证。 前端的一切都没问题,但我无法在前端处理后端验证(根据后端验证手动将控件标记为无效)。
问题在于填充带有错误的表单控件,看起来我不能只this.formBuiltWithFormBuilder.setErrors()
并传递一个有错误的对象来自动填充表单中包含的所有控件 - 因为当所有字段状态保持this.formBuiltWithFormBuilder.setErrors()
时,只有表单变为无效相同。
所以目前我正在尝试做类似的事情:
// Example of incoming formErrors:
// (it can also be nested for nested forms)
// {
// phone: {
// phoneNumberNoMatch: "The input does not match..."
// }
// }
@Input() public formErrors: ValidationErrors;
public detailsForm: FormGroup;
public ngOnInit() {
this.createForm();
}
public ngOnChanges() {
this.updateFormErrors(this.formErrors);
}
private createForm(account: AccountInterface) {
this.detailsForm = this.fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required]
});
}
private updateFormErrors(errors: any) {
if (this.detailsForm) {
// Trying to populate included form controls with errors
this.detailsForm.setErrors(errors);
}
}
```
我还考虑过遍历错误对象并为每个控件手动应用错误,但我认为这个解决方案并不理想,因为可能存在嵌套表单。
那么它是一种自动填充错误的表单控件的方法吗?
看起来没有内置的解决方案,所以我创建了一个表单助手类来填充错误。 理论上它也应该填充嵌套/数组形式,但我只测试了它的普通形式。 如果没有,请告诉我;)
它使用lodash/map
方法遍历errors对象。
import { FormGroup, FormControl, FormArray } from '@angular/forms';
import { map } from 'lodash';
export class FormHelper {
public static POPULATE_FORM_GROUP_ERRORS(
rootFormGroup: FormGroup,
errors: any
) {
map(rootFormGroup.controls, (control, name) => {
if (control instanceof FormControl) {
if (errors.hasOwnProperty(name)) {
control.setErrors(errors[name]);
}
}
if (control instanceof FormGroup) {
if (errors.hasOwnProperty(name)) {
FormHelper.POPULATE_FORM_GROUP_ERRORS(control, errors[name]);
}
}
if (control instanceof FormArray) {
if (errors.hasOwnProperty(name) && errors[name] instanceof Array) {
this.iterateOverFormArrayControl(control, errors[name]);
}
}
});
}
private static iterateOverFormArrayControl(
formArray: FormArray,
errors: any[]
) {
errors.forEach((error: any, index: number) => {
const arrayControl = formArray.at(index);
if (arrayControl && arrayControl instanceof FormControl) {
arrayControl.setErrors(error);
}
if (arrayControl && arrayControl instanceof FormGroup) {
FormHelper.POPULATE_FORM_GROUP_ERRORS(arrayControl, error);
}
if (arrayControl && arrayControl instanceof FormArray && error instanceof Array) {
FormHelper.iterateOverFormArrayControl(arrayControl, error);
}
});
}
}
所以现在我的表单看起来像:
// ... Somewhere at the top
import { FormHelper } from '@app/commons/FormHelper';
// ...
// Example of incoming formErrors:
// (it can also be nested for nested forms)
// {
// phone: {
// phoneNumberNoMatch: "The input does not match..."
// }
// }
@Input() public formErrors: ValidationErrors;
public detailsForm: FormGroup;
public ngOnInit() {
this.createForm();
}
public ngOnChanges() {
this.updateFormErrors(this.formErrors);
}
private createForm(account: AccountInterface) {
this.detailsForm = this.fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required]
});
}
private updateFormErrors(errors: any) {
if (this.detailsForm) {
// Populate included form controls with errors
FormHelper.POPULATE_FORM_GROUP_ERRORS(this.detailsForm, errors);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.