Dans AngularJS, vous pouviez spécifier des observateurs pour observer les changements dans les variables de portée en utilisant la $watch
fonction de $scope
. Quel est l'équivalent de surveiller les changements de variables (dans, par exemple, les variables de composants) dans Angular?
213
Réponses:
Dans Angular 2, la détection des changements est automatique ...
$scope.$watch()
et$scope.$digest()
RIPMalheureusement, la section Détection des changements du guide de développement n'est pas encore écrite (il y a un espace réservé au bas de la page Présentation de l' architecture , dans la section "Les autres choses").
Voici ma compréhension du fonctionnement de la détection des modifications:
setTimeout()
intérieur de nos composants plutôt que quelque chose comme$timeout
... parce que lesetTimeout()
singe est patché.ChangeDetectorRef
.) Ces détecteurs de changement sont créés lorsque Angular crée des composants. Ils gardent une trace de l'état de toutes vos fixations, pour un contrôle sale. Celles-ci sont, dans un sens, similaires à l'automatique$watches()
qu'Angular 1 mettrait en place pour{{}}
les liaisons de modèles.Contrairement à Angular 1, le graphique de détection de changement est un arbre dirigé et ne peut pas avoir de cycles (cela rend Angular 2 beaucoup plus performant, comme nous le verrons ci-dessous).
onPush
stratégie de détection des modifications sur aucun de vos composants), chaque composant de l'arborescence est examiné une fois (TTL = 1) ... à partir du haut, dans le premier ordre de profondeur. (Eh bien, si vous êtes en mode dev, la détection des modifications s'exécute deux fois (TTL = 2). Voir ApplicationRef.tick () pour plus d'informations.)Si les données de composant que vous souhaitez regarder sont une propriété d'entrée primitive (chaîne, booléenne, nombre), vous pouvez l'implémenter
ngOnChanges()
pour être averti des modifications.Si la propriété d'entrée est un type de référence (objet, tableau, etc.), mais que la référence n'a pas changé (par exemple, vous avez ajouté un élément à un tableau existant), vous devrez l'implémenter
ngDoCheck()
(voir cette réponse SO pour plus d'informations) sur ce).Vous ne devez modifier que les propriétés du composant et / ou les propriétés des composants descendants (en raison de l'implémentation de l'arborescence unique - c'est-à-dire du flux de données unidirectionnel). Voici un plongeur qui viole cela. Des tuyaux dynamiques peuvent également vous faire trébucher ici.
Autres références pour en savoir plus:
onPush
.la source
host
"Host Listeners" dans le document API DirectiveMetadata . Il explique comment écouter les événements globaux depuis l'intérieur de la zone angulaire (donc la détection de changement sera déclenchée comme vous le souhaitez). Cette réponse a un plongeur qui fonctionne.Ce comportement fait désormais partie du cycle de vie des composants.
Un composant peut implémenter la méthode ngOnChanges dans l' interface OnChanges pour accéder aux modifications d'entrée.
Exemple:
la source
Si, en plus de la liaison bidirectionnelle automatique, vous souhaitez appeler une fonction lorsqu'une valeur change, vous pouvez casser la syntaxe de raccourci de la liaison bidirectionnelle vers la version plus détaillée.
<input [(ngModel)]="yourVar"></input>
est un raccourci pour
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(voir par exemple http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Vous pouvez faire quelque chose comme ça:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
la source
Vous pouvez utiliser
getter function
ouget accessor
pour agir comme montre sur angulaire 2.Voir la démo ici .
la source
Voici une autre approche utilisant les fonctions getter et setter pour le modèle.
la source
(change)
gestionnaire (s) sur chacun d'entre eux; Je ne veux pas ajouter deget|sets
s à chaque propriété de mon modèle; il ne sera pas utile d'ajouter unget|set
pourthis.object
;ngOnChanges()
détecte uniquement les modifications apportées à l'@Input
art . Sainte manne! Que nous ont-ils fait ??? Rendez-nous une sorte de veille profonde!Si vous souhaitez le rendre contraignant dans les deux sens, vous pouvez l'utiliser
[(yourVar)]
, mais vous devez implémenter l'yourVarChange
événement et l'appeler à chaque fois que votre variable change.Quelque chose comme ça pour suivre le changement de héros
puis quand votre héros est changé, appelez
this.heroChange.emit(this.hero);
la
[(hero)]
reliure fera le reste pour vousvoir l'exemple ici:
http://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview
la source
Essayez quand votre demande encore exige
$parse
,$eval
,$watch
comme le comportement dans angulairehttps://github.com/vinayk406/angular-expression-parser
la source
Cela ne répond pas directement à la question, mais j'ai à plusieurs reprises atterri sur cette question de débordement de pile afin de résoudre quelque chose que j'utiliserais $ watch for dans angularJs. J'ai fini par utiliser une autre approche que celle décrite dans les réponses actuelles, et je veux la partager au cas où quelqu'un la trouverait utile.
La technique que j'utilise pour réaliser quelque chose de similaire
$watch
est d'utiliser unBehaviorSubject
( plus sur le sujet ici ) dans un service Angular, et de laisser mes composants s'y abonner afin d'obtenir (regarder) les changements. Ceci est similaire à un$watch
dans angularJs, mais nécessite plus de configuration et de compréhension.Dans ma composante:
À mon service
Voici une démo sur Stackblitz
la source