2016-11-18 77 views
14

所有验证错误,鉴于此代码:得到角2 FormGroup

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

我怎样才能得到this.form所有验证错误?

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

回答

21

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

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]); 
     }); 
     } 
    }); 
    } 

表单名称productForm应改为你的。

它的工作原理如下:我们从格式{[p: string]: AbstractControl}的格式获取所有控件,并通过每个错误键进行迭代,以获取错误的详细信息。它跳过null错误值。

它也可以更改为在模板视图中显示验证错误,只需将console.log(..)替换为您需要的值即可。

+0

如何用相同的模式扩展FormArray的上述方法? –

-1

您可以迭代this.form.errors属性。

+12

我想'''this.form.errors''只会返回this.form'验证的错误,而不会返回'''this.form.controls'''。您可以分别验证FormGroups及其子项(任意数量的FormGroups,FormControls和FormArrays)。为了获取所有错误,我认为你需要递归地询问它们。 –

1
export class GenericValidator { 
    constructor(private validationMessages: { [key: string]: { [key: string]: string } }) { 
    } 

processMessages(container: FormGroup): { [key: string]: string } { 
    const messages = {}; 
    for (const controlKey in container.controls) { 
     if (container.controls.hasOwnProperty(controlKey)) { 
      const c = container.controls[controlKey]; 
      if (c instanceof FormGroup) { 
       const childMessages = this.processMessages(c); 
       // handling formGroup errors messages 
       const formGroupErrors = {}; 
       if (this.validationMessages[controlKey]) { 
        formGroupErrors[controlKey] = ''; 
        if (c.errors) { 
         Object.keys(c.errors).map((messageKey) => { 
          if (this.validationMessages[controlKey][messageKey]) { 
           formGroupErrors[controlKey] += this.validationMessages[controlKey][messageKey] + ' '; 
          } 
         }) 
        } 
       } 
       Object.assign(messages, childMessages, formGroupErrors); 
      } else { 
       // handling control fields errors messages 
       if (this.validationMessages[controlKey]) { 
        messages[controlKey] = ''; 
        if ((c.dirty || c.touched) && c.errors) { 
         Object.keys(c.errors).map((messageKey) => { 
          if (this.validationMessages[controlKey][messageKey]) { 
           messages[controlKey] += this.validationMessages[controlKey][messageKey] + ' '; 
          } 
         }) 
        } 
       } 
      } 
     } 
    } 
    return messages; 
} 
} 

我把它从Deborahk并修改它一点点。

5

这与FormGroup内部支撑件(like here

测试在溶液:角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; 
} 

使用示例

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; 
} 
+0

谢谢!这正是我正在寻找的解决方案。 –

+0

完美作品:)谢谢! +1 –

0

或者,你可以使用这个库来获取所有的错误,甚至深刻的和动态的形式

npm install --save angular-super-validator 

然后,只需通过FormGroup获取所有你的错误

const errorsFlat = SuperForm.getAllErrorsFlat(fg); 
console.log(errors); 
0
// IF not populated correctly - you could get aggregated FormGroup errors object 
let getErrors = (formGroup: FormGroup, errors: any = {}) { 
    Object.keys(formGroup.controls).forEach(field => { 
    const control = formGroup.get(field); 
    if (control instanceof FormControl) { 
     errors[field] = control.errors; 
    } else if (control instanceof FormGroup) { 
     errors[field] = this.getErrors(control); 
    } 
    }); 
    return errors; 
} 

// Calling it: 
let formErrors = getErrors(this.form); 
0

我使用的是角5,你可以简单地使用FormGroup检查你的表单的状态属性,例如

this.form = new FormGroup({ 
     firstName: new FormControl('', [Validators.required, validateName]), 
     lastName: new FormControl('', [Validators.required, validateName]), 
     email: new FormControl('', [Validators.required, validateEmail]), 
     dob: new FormControl('', [Validators.required, validateDate]) 
    }); 

除非所有字段都通过所有验证规则,否则this.form.status将为“INVALID”。

最好的部分是它可以实时检测到变化。

+0

是的,但我们需要得到整个表单组的错误,而不只是知道它是否有效 –