Setting errors on a FormGroup instance in Angular

2019-06-07 09:03发布

问题:

I'm using Angular 4.4.3 reactive forms to implement custom validation for a group of controls in a form. The method AbstractControl.setErrors, according to docs updates the errors property of the AbstractControl, upon which it's invoked, updates the status of its parent, but not the parents errors property. I wanted to set the errors property on a FormGroup instance, so I use the setErrors inherited by the FormGroup. However, it does not update errors as expected.

Following is my sample code: Trying it on FormControl instances, does update their errors as well as their parents' validity status (not the parents errors though!):

let myFormGroup 
    = this._formBuilder
          .group({
                   ctrl1: [null],
                   ctrl2: [null]
                 }, 
                 {
                   validator: (fg: FormGroup) => {
                                   let ctrl1 = fg.get('ctrl1'),
                                       ctrl2 = fg.get('ctrl2'),
                                       ctrl1Empty = !ctrl1.value,
                                       ctrl2Empty = !ctrl2.value;

                                       //Successfully sets ctrl1.errors and fg.status, but not fg.errors 
                                       if (ctrl1empty)
                                         ctrl1.setErrors({ctrl1required: true});
                                       //Successfully sets ctrl2.errors and fg.status, but not fg.errors 
                                       if (ctrl2Empty)
                                         ctrl2.setErrors({ctrl2required: true});
                                       //Doesn't work, doesn't update fg.errors
                                       if (ctrl1Empty && ctrl2Empty)
                                         fg.setErrors({required: true});
                              }
                 })

Any idea why?

回答1:

So, thanks to @incognito's confirmation, I figured out where the problem was after further inspection.

setErrors, does set the errors property of the form group instance. However, the custom validator shown in my question doesn't explicitly return a value (i.e. a falsey undefined value). Looking into the code of the reactive forms module in angular, I found this method, which merges errors raised by various validators in this line, the method checks whether errors (undefined in my code snippet) is not equal to null. This condition (as inspected in its es5 version) evaluates to false, which causes the result to be null, thus ignoring the content of the errors property set in the code. The lesson I learned is: always return a value from custom validators, even if further nested FormGroup instances have their own custom logic for setting errors.