Búsqueda de sitios web

javascript - Angular 2: Actualizar el validador de FormControl después de valueChanges


¿Hay alguna forma de actualizar los Validtors de un objeto FormControl? Tengo un FormGroup donde una entrada es un campo select, cuando el valor del campo select cambia quiero que el otro FormControl en mi FormGroup cambie el validador.

Aquí está mi método subscribeToFormChanges() de mi componente 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));
      }
    });
  }

Y aquí está la plantilla 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
    
  </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
    
  </div>
</div>

Cuando estoy implementando el método subscribeToFormChanges() como se muestra aquí, appsForm.controls.appId.value deja de actualizarse al escribir en el campo de entrada. Inicialmente, el valor se está actualizando.

Respuesta #1

Resolví el problema escuchando valueChanges en mi campo de selección de plataforma y luego uso el método setValidators() en el campo de entrada appId. Este artículo fue bastante útil.

Aquí está mi solución:

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

Respuesta #2

Para volver a verificar los controles dentro de un FormGroup, puedes hacer algo con el updateValueAndValidity del FormControl.

Si this.appsForm es de hecho un FormGroup:

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

Artículos relacionados