Angular form updateValueAndValidity of all children controls

后端 未结 5 565
攒了一身酷
攒了一身酷 2020-12-29 01:50

In my Angular 4 app, I have a form with several controls.

At some points I need to force the update of their validity, so I\'m doing:

this.form.get(\         


        
相关标签:
5条回答
  • 2020-12-29 02:32

    It is not possible at the moment to update the descendants of an AbstractControl (FormGroup, ...) with the AbstractControl itself. Maybe in a future release it will be possible.

    https://github.com/angular/angular/issues/6170

    https://github.com/angular/angular/issues/22166

    update: a pull request is already open https://github.com/angular/angular/pull/19829

    0 讨论(0)
  • 2020-12-29 02:37

    I ran into the same problem, one of the issues was that listening to the valueChanges observable and triggering updateValueAndValidity to run my validators caused an endless loop, so to resolve (and somewhat hacky ?) I created the component variable validityCycleFired and initialized as false, that I toggle and it prevents a runaway loop:

    const fireValidityCheck = () => {
         if (this.validityCycleFired) return;
         this.validityCycleFired = true;
         this.passwordForm.get('old_password').updateValueAndValidity();
         this.passwordForm.get('new_password').updateValueAndValidity();
         this.passwordForm.get('confirm_new_password').updateValueAndValidity();
         setTimeout(() => this.validityCycleFired = false, 15);
         return;
    };
    this.passwordForm.valueChanges.subscribe(fireValidityCheck);
    
    0 讨论(0)
  • 2020-12-29 02:42

    I had the same situation for me to update FormGroup | FormArray at nested level controls.

    check this out(worked for me):

    /**
     * Re-calculates the value and validation status of the entire controls tree.
     */
    function updateTreeValidity(group: FormGroup | FormArray): void {
      Object.keys(group.controls).forEach((key: string) => {
        const abstractControl = group.controls[key];
    
        if (abstractControl instanceof FormGroup || abstractControl instanceof FormArray) {
          updateTreeValidity(abstractControl);
        } else {
          abstractControl.updateValueAndValidity();
        }
      });
    }
    
    0 讨论(0)
  • 2020-12-29 02:42
    validateFormFields(fields) {
        try {
          Object.entries(fields.controls).forEach((control: any) => {
            if (typeof control[0] == 'Array' 
            ) {
              this.validateFormFields(control[1]);
            } else {
              if (control[1].controls) {
                Object.entries(control[1].controls).forEach((c: any) => {
                  c[1].touched = true;
                });
              } else {
                control[1].touched = true;
              }
    
            }
          });
        } catch (e) {
          console.log(e);
        }
      }
    
    0 讨论(0)
  • 2020-12-29 02:53

    I solved my issue, which was similar to yours, by recursing the controls and manually triggering the update. Probably this is not an optimal solution:

    private triggerValidation(control: AbstractControl) {
        if (control instanceof FormGroup) {
            const group = (control as FormGroup);
    
            for (const field in group.controls) {
                const c = group.controls[field];
    
                this.triggerValidation(c);
            }
        }
        else if (control instanceof FormArray) {
            const group = (control as FormArray);
    
            for (const field in group.controls) {
                const c = group.controls[field];
    
                this.triggerValidation(c);
            }
        }
    
        control.updateValueAndValidity({ onlySelf: false });
    }
    
    0 讨论(0)
提交回复
热议问题