从Angular 2 FormGroup获取所有验证错误

Eag*_*eak 61 validation typescript angular

鉴于此代码:

this.form = this.formBuilder.group({
      email: ['', [Validators.required, EmailValidator.isValid]],
      hasAcceptedTerms: [false, Validators.pattern('true')]
    });
Run Code Online (Sandbox Code Playgroud)

如何从中获取所有验证错误this.form

我正在编写单元测试,并希望在断言消息中包含实际的验证错误.

Ale*_*mov 93

我遇到了同样的问题,为了找到所有验证错误并显示它们,我写了下一个方法:

getFormValidationErrors() {
  Object.keys(this.productForm.controls).forEach(key => {

  const controlErrors: ValidationErrors = this.productForm.get(key).errors;
  if (controlErrors != null) {
        Object.keys(controlErrors).forEach(keyError => {
          console.log('Key control: ' + key + ', keyError: ' + keyError + ', err value: ', controlErrors[keyError]);
        });
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

表格名称productForm应更改为您的名称.

它以下一种方式工作:我们从格式中获取所有控件,{[p: string]: AbstractControl}并按每个错误键进行迭代,以获取错误的详细信息.它会跳过null错误值.

它也可以更改为在模板视图上显示验证错误,只需替换console.log(..)为您需要的内容.

  • 如何以相同的模式为 FormArray 扩展上述方法? (2认同)
  • 请注意,这不适用于嵌套 FormGroups,我建议使用 Mayur Dongre 的方法 (2认同)

Mix*_*OID 24

这是FormGroup内部支持的解决方案(像这里)

测试:Angular 4.3.6

得到形式验证,errors.ts

import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms';

export interface AllValidationErrors {
  control_name: string;
  error_name: string;
  error_value: any;
}

export interface FormGroupControls {
  [key: string]: AbstractControl;
}

export function getFormValidationErrors(controls: FormGroupControls): AllValidationErrors[] {
  let errors: AllValidationErrors[] = [];
  Object.keys(controls).forEach(key => {
    const control = controls[ key ];
    if (control instanceof FormGroup) {
      errors = errors.concat(getFormValidationErrors(control.controls));
    }
    const controlErrors: ValidationErrors = controls[ key ].errors;
    if (controlErrors !== null) {
      Object.keys(controlErrors).forEach(keyError => {
        errors.push({
          control_name: key,
          error_name: keyError,
          error_value: controlErrors[ keyError ]
        });
      });
    }
  });
  return errors;
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

if (!this.formValid()) {
  const error: AllValidationErrors = getFormValidationErrors(this.regForm.controls).shift();
  if (error) {
    let text;
    switch (error.error_name) {
      case 'required': text = `${error.control_name} is required!`; break;
      case 'pattern': text = `${error.control_name} has wrong pattern!`; break;
      case 'email': text = `${error.control_name} has wrong email format!`; break;
      case 'minlength': text = `${error.control_name} has wrong length! Required length: ${error.error_value.requiredLength}`; break;
      case 'areEqual': text = `${error.control_name} must be equal!`; break;
      default: text = `${error.control_name}: ${error.error_name}: ${error.error_value}`;
    }
    this.error = text;
  }
  return;
}
Run Code Online (Sandbox Code Playgroud)

  • Angular 5 更改 - const controlErrors: ValidationErrors = form.controls[key].errors; (2认同)

Arn*_*uTG 11

从 Angular 表单中检索所有错误的递归方法,在创建任何类型的公式结构后,无法从表单中检索所有错误。这对于调试目的非常有用,而且对于绘制这些错误也非常有用。

已针对 Angular 9 进行测试

getFormErrors(form: AbstractControl) {
    if (form instanceof FormControl) {
        // Return FormControl errors or null
        return form.errors ?? null;
    }
    if (form instanceof FormGroup) {
        const groupErrors = form.errors;
        // Form group can contain errors itself, in that case add'em
        const formErrors = groupErrors ? {groupErrors} : {};
        Object.keys(form.controls).forEach(key => {
            // Recursive call of the FormGroup fields
            const error = this.getFormErrors(form.get(key));
            if (error !== null) {
                // Only add error if not null
                formErrors[key] = error;
            }
        });
        // Return FormGroup errors or null
        return Object.keys(formErrors).length > 0 ? formErrors : null;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 那么 FormArray 呢? (2认同)
  • @greg93 将第二个条件替换为 `form instanceof FormGroup || FormArray 的表单实例` (2认同)

And*_*ber 7

这是另一个变种,它以递归方式收集错误,并且不依赖于任何外部库,例如lodash(仅ES6):

function isFormGroup(control: AbstractControl): control is FormGroup {
  return !!(<FormGroup>control).controls;
}

function collectErrors(control: AbstractControl): any | null {
  if (isFormGroup(control)) {
    return Object.entries(control.controls)
      .reduce(
        (acc, [key, childControl]) => {
          const childErrors = collectErrors(childControl);
          if (childErrors) {
            acc = {...acc, [key]: childErrors};
          }
          return acc;
        },
        null
      );
  } else {
    return control.errors;
  }
}
Run Code Online (Sandbox Code Playgroud)


Pia*_*M4n 6

或者您可以使用此库来获取所有错误,甚至可以从深层和动态表单中获取.

npm install --save npm i @naologic/forms
Run Code Online (Sandbox Code Playgroud)

你会想要的

import {SuperForm} from 'npm i @naologic/forms';

然后只需传递FormGroup即可获取所有错误

const errorsFlat = SuperForm.getAllErrorsFlat(fg); 
console.log(errorsFlat);
Run Code Online (Sandbox Code Playgroud)

更新:

您可以使用npm i @naologic/forms和使用NaoFromGroup而不是角度的经典表单组.它有一些新功能,你也可以得到所有错误.

抱歉,还没有文档,只需查看代码即可.

更新:

lib需要angular 6,因为它使用AbstractControlOptions