Il est possible de souscrire un rappel à une propriété observable NgForm
de valueChanges
afin de réagir aux modifications des valeurs des contrôles du formulaire.
De la même manière, j'ai besoin de réagir à l'événement de l'utilisateur touchant l'un des contrôles de formulaire.
Cette classe semble définir l'observable valueChanges
et la propriété touched
est définie comme un booléen.
Existe-t-il un moyen de réagir à l'événement "contrôle touché"?
Il n'y a pas de moyen direct fourni par ng2 pour réagir à un événement touché. Il utilise ( input ) event pour déclencher les événements valueChanges et ( blur ) pour définir touché/inaltéré propriété de AbstractControl ..__ devez souscrire manuellement à l'événement souhaité dans le modèle et le gérer dans votre classe de composants.
Vous pouvez étendre la classe FormControl
par défaut et ajouter la méthode markAsTouched
qui appellera la méthode native, plus votre effet secondaire.
import { Injectable } from '@angular/core';
import { FormControl, AsyncValidatorFn, ValidatorFn } from '@angular/forms';
import { Subscription, Subject, Observable } from 'rxjs';
export class ExtendedFormControl extends FormControl {
statusChanges$: Subscription;
touchedChanges: Subject<boolean> = new Subject<boolean>();
constructor(
formState: Object,
validator: ValidatorFn | ValidatorFn[] = null,
asyncValidator: AsyncValidatorFn | AsyncValidatorFn[] = null
) {
super(formState, validator, asyncValidator);
this.statusChanges$ = Observable.merge(
this.valueChanges,
this.touchedChanges.distinctUntilChanged()
).subscribe(() => {
console.log('new value or field was touched');
});
}
markAsTouched({ onlySelf }: { onlySelf?: boolean } = {}): void {
super.markAsTouched({ onlySelf });
this.touchedChanges.next(true);
}
}
Si votre problème ressemblait beaucoup au mien, j'essayais de marquer un champ comme étant touché dans un composant, puis de répondre à cela dans un autre. J'ai eu accès à la AbstractControl
pour ce champ. La façon dont je me débrouillais était
field.markAsTouched();
(field.valueChanges as EventEmitter<any>).emit(field.value);
Et puis je viens de souscrire à valueChanges dans mon autre composant. À noter: field.valueChanges
est exporté en tant qu'observable, mais au moment de l'exécution, il s'agit d'une EventEmitter
, ce qui en fait une solution moins que belle. L’autre limite de cette situation serait évidemment le fait que vous souscrivez à beaucoup plus que le simple état touché.