web-dev-qa-db-fra.com

Comment lancer le `valueChanges` par programme?

Sur l’une de mes pages, j’utilise FormBuilder pour remplir un formulaire lors de l’initialisation. Chaque entrée obtient une classe chaque fois que l'entrée est pas vide. Cela est fait en ajoutant une ngClass à chaque entrée et en vous abonnant à la FormGroup 's valueChanges.

Mon problème se produit chaque fois que le formulaire est rempli par programme. Chaque fois qu'un utilisateur modifie une valeur du formulaire, valueChanges est appelé, mais ce n'est pas le cas lorsque vous utilisez FormBuilder.

Ma question est la suivante: comment faire en sorte que l'événement valueChanges soit déclenché chaque fois que la FormBuilder est terminée.

J'ai essayé d'utiliser this.FormGroup.updateValueAndValidity(), mais cela n'a abouti à rien.

13
Max

J'ai trouvé une solution qui a fonctionné pour moi. J'ai oublié deux paramètres dans la fonction updateValueAndValidity.

  • onlySelf: ne mettra à jour cette FormControl que si elle est vraie.
  • emiteEvent: provoquera le déclenchement de l'événement valueChanges lorsque la valeur est true.

En conséquence, vous obtiendrez quelque chose comme: FormGroup.updateValueAndValidity({ onlySelf: false, emitEvent: true });

11
Max

Le titre et la description de votre question sont un peu trompeurs. Lequel est-ce? (je)

  • Voulez-vous mettre à jour le statut de validité d'un champ lors de la modification de sa valeur par programme?
  • Ou voulez-vous vous assurer que votre abonnement à la valueChanges d'un champ soit appelé lors du changement de sa valeur par programme?

Quoi qu'il en soit, consultez ce Plunkr: https://plnkr.co/edit/4V4PUFI1D15ZDWBfm2hb?p=preview

Vous verrez que lorsque vous définissez la valeur du champ par programme comme ceci:

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

La validité et l'observable valueChanges du champ sont mis à jour. On dirait donc que vous essayez de recréer un comportement déjà présent.

Toutefois, la propriété dirty du champ N'EST PAS mise à jour lors de la modification de sa valeur par programme (comme selon le document : "Un contrôle est modifié si l'utilisateur a modifié la valeur dans l'interface utilisateur"). Peut-être que vous vérifiez la propriété dirty pour indiquer des erreurs de champ et que vous avez l'illusion que le statut de validité n'est pas mis à jour, alors qu'en fait c'est juste la propriété dirty qui ne l'est pas?

(i) Ces deux choses sont différentes. Vous ne devez PAS souscrire à valueChanges pour déclencher manuellement la validation. La validation doit être imposée en déclarant les validateurs dans votre modèle de formulaire.

2
AngularChef

Votre question n'est pas claire à 100%, mais je pense que ce que vous dites est la suivante:

Mon valueChanges fonctionne correctement lorsque je modifie quelque chose dans l'interface utilisateur, mais je souhaite déclencher la logique de ma fonction d'abonnement dès que j'ai fini d'initialiser l'objet FormBuilder dans mon constructeur pour gérer les conditions initiales.

Dans ce cas, ce que je fais est assez simple:

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

initialValues correspond aux données brutes avec lesquelles vous avez initialisé le formulaire. Vous pourriez probablement simplement mettre dans searchForm.getRawValue() aussi.

Cela fait que l'observable tire immédiatement.

Remarque: ceci utilise la nouvelle commande pipe - qui sera requise à partir de RxJS7. Il est donc recommandé de l’utiliser ici. Vieux style RxJS est juste à faire valueChanges.startWith(initialValues).subscribe...

1
Simon_Weaver