Saltar al contenido

¿Cómo activar `valueChanges` mediante programación?

Si te encuentras con algo que no entiendes puedes dejarnos un comentario y trataremos de ayudarte lo más rápido posible.

Solución:

Encontré una solución que funcionó para mí. Olvidé dos parámetros en el updateValueAndValidity función.

  • onlySelf: solo actualizará esto FormControl Cuándo true.
  • emitEvent: causará valueChanges evento que se disparará cuando true.

Así que como resultado obtendrás algo como:
FormGroup.updateValueAndValidity( onlySelf: false, emitEvent: true );

Su pregunta no es 100% clara, pero creo que lo que está diciendo:

Mi valueChanges funciona bien cuando cambia algo en la interfaz de usuario, pero quiero activar la lógica de mi función de suscripción tan pronto como termine de inicializar el objeto FormBuilder en mi constructor para manejar las condiciones iniciales.

En ese caso lo que hago es bastante simple:

    this.searchForm.valueChanges
        .pipe(startWith(initialValues)).subscribe(value =>
        
            // whatever you want to do here
        );

initialValues son los datos sin procesar con los que ha inicializado el formulario. Probablemente podrías simplemente poner searchForm.getRawValue() también.

Esto solo hace que el observable se dispare inmediatamente.


Importante: hay un problema sutil con la respuesta original si está utilizando la canalización asíncrona para suscribirse en lugar de una explícita subscribe().

En Angular, puede suscribirse explícitamente a un observable (como se muestra arriba), pero es igualmente común usar la tubería asíncrona. Un ejemplo se ve así:

model = 
   firstName: this.searchForm.valueChanges.pipe(startWith(initialValues), map(values => values.firstName.toUpperCase())
;

y luego en su plantilla muestre el valor del formulario:

First name:  async 

Hay un problema con este enfoque que es bastante sutil.

  • los startWith el operador capturará el valor cuando creas el observableque será correcto la primera vez.
  • Sin embargo, si vuelve a suscribirse al observable, seguirá usando los valores originales, incluso si el formulario ha cambiado. Esto puede manifestarse si la interfaz de usuario está oculta y luego se vuelve a mostrar (lo que provoca una nueva suscripción).

Soluciones posibles:

  1. Utilizar defer tal que el valor de this.searchForm.value se evaluará cada vez que se suscriba el observable.

    defer(() => this.searchForm.valueChanges.pipe(startWith(this.searchForm.value), 
                map(values => values.firstName.toUpperCase())
    
  2. Utilizar shareReplay. Esto solo funciona aquí con refCount: false y por lo tanto yo no lo recomiendo ya que no se limpiará correctamente.

    this.searchForm.valueChanges.pipe(startWith(initialValues), 
                 map(values => values.firstName.toUpperCase(), 
                 shareReplay( refCount: false, bufferSize: 1 )
    
  3. Hipotético: Si startWith tenía una lambda entonces podrías usar eso. Desafortunadamente no lo hace en este momento:

    startWith(() => this.searchForm.value)
    

Nota: si está utilizando subscribe explícitamente entonces no necesita preocuparse por este problema.

El título y la descripción de su pregunta son un poco engañosos. ¿Cuál es? (I)

  • ¿Desea actualizar el estado de validez de un campo al cambiar su valor mediante programación?
  • ¿O quieres asegurarte de que tu suscripción a la valueChanges de un campo se llama al cambiar su valor programáticamente?

De todos modos, mira este Plunkr: https://plnkr.co/edit/4V4PUFI1D15ZDWBfm2hb?p=preview

Verá que cuando establece el valor del campo mediante programación de esta manera:

this.myForm.get('myField').setValue(newValue);

Tanto la validez como la valueChanges observables para el campo se actualizan. Entonces, parece que estás tratando de recrear un comportamiento que ya está aquí.

sin embargo, el dirty La propiedad del campo NO se actualiza al cambiar su valor mediante programación (según el documento: “Un control está sucio si el usuario ha cambiado el valor en la interfaz de usuario“). ¿Podría ser que estés comprobando el dirty propiedad para indicar errores de campo y que tiene la espejismo que no se actualiza el estado de vigencia, cuando en realidad es solo el dirty ¿Propiedad que no está actualizada?

(i) Estas dos cosas son diferentes. NO debes suscribirte a valueChanges para activar manualmente la validación. La validación debe aplicarse declarando validadores en su modelo de formulario.

Si para ti ha sido de utilidad nuestro post, sería de mucha ayuda si lo compartieras con el resto desarrolladores de esta forma contrubuyes a difundir esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *