web-dev-qa-db-fra.com

Angular 2: Mettre à jour le validateur FormControl après valueChanges

Existe-t-il un moyen de mettre à jour la Validtors d'un objet FormControl? J'ai FormGroup où une entrée est un champ de sélection, lorsque la valeur du champ de sélection change, je souhaite que l'autre FormControl de mon groupe de formulaires change de validateur. 

Voici ma méthode subscribeToFormChanges() de mon composant FormGroup:

private appIdRegexes = {
    ios: /^[a-zA-Z][a-zA-Z0-9]*(\.[a-zA-Z0-9\-]+){2,}$/,
    Android: /^([a-zA-Z])[a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9\-]*){2,}$/,
    any: /^any$/
  };

private subscribeToFormChanges(): void {
    const myFormValueChanges$ = this.appsForm.valueChanges;
    myFormValueChanges$.subscribe(x => {
      const platform = this.appsForm.controls['platform'].value;
      const appId = this.appsForm.controls['appId'].value;

      if (this.appIdRegexes[platform]) {
        this.appsForm.controls['appId'] = new FormControl(appId, Validators.pattern(this.appIdRegexes[platform].source));
      }
    });
  }

Et voici le modèle html:

<div class="row" [formGroup]="appsForm">
  <div class="form-group col-xs-6">
    <label>Platform</label>

    <select id="licensePlatform" class="form-control"
            formControlName="platform">
      <option *ngFor="let platform of licensePlatforms" [value]="platform">
        {{platform}}
      </option>
    </select>

    <small [hidden]="appsForm.controls.platform.valid">
      Platform is required
    </small>
  </div>

  <div class="form-goup col-xs-6">
    <label>App ID</label>
    <input type="text" class="form-control" formControlName="appId">
    <small [hidden]="appsForm.controls.appId.valid">
      Please use the right ID format
    </small>
  </div>
</div>

Lorsque j'implémente la méthode subscribeToFormChanges() comme indiqué ici, appsForm.controls.appId.value ne se met plus à jour lors de l'écriture dans le champ de saisie. Initialement, la valeur est mise à jour.

12
Markus Török

J'ai résolu le problème en écoutant valueChanges sur le champ de sélection de ma plate-forme, puis j'utilisais la méthode setValidators() dans le champ d'entrée appId. Cet article était très utile.

Voici ma solution:

 private subscribePlatformChanges() {
    const platformCtrl = this.appsForm.controls['platform'];
    const changes$ = platformCtrl.valueChanges;

    changes$.subscribe(platform => {
      this.appsForm.controls['appId'].setValidators([Validators.pattern(this.appIdRegexes[platform].source),
                                                    Validators.required]);
      this.appsForm.controls['appId'].updateValueAndValidity();
    });
  }
10
Markus Török

Pour revérifier les contrôles dans une FormGroup, vous pouvez faire quelque chose avec le updateValueAndValidity du FormControl

Si this.appsForm est bien une FormGroup:

this.appsForm.controls.forEach(control => control.updateValueAndValidity());
3
PierreDuc

vous pouvez déclencher un événement de changement à partir de la sélection ci-dessous

<select id="licensePlatform" class="form-control"
            formControlName="platform"  (change)="update($event.target.value)" >
      <option selected="selected" disabled="disabled" value="">Select Card Type</option>
      <option *ngFor="let platform of licensePlatforms" [value]="platform" >
        {{platform}}
      </option>
    </select>

Et dans le composant, vous pouvez écrire la fonction de mise à jour comme ci-dessous

update(value){
      if(value){
        (<FormControl>this.appsForm.controls['platform']).setValue(value, {onlySelf: false});
        const appId = this.appsForm.controls['appId'].value;
        if (this.appIdRegexes[value]) {
        this.appsForm.controls['appId'] = new FormControl(appId, Validators.pattern(this.appIdRegexes[value].source));
      }
    };

  }

Cela mettra à jour le validateur en fonction du choix que vous aurez fait dans la liste déroulante .. Je crois que cela résoudra votre problème.

0
znwz