Existe-t-il un moyen de s'abonner à des événements sur plusieurs objets en utilisant la fonction $watch
Par exemple
$scope.$watch('item1, item2', function () { });
Existe-t-il un moyen de s'abonner à des événements sur plusieurs objets en utilisant la fonction $watch
Par exemple
$scope.$watch('item1, item2', function () { });
À partir d'AngularJS 1.3, il y a une nouvelle méthode appelée $watchGroup
pour l'observation d'un ensemble d'expressions.
$scope.foo = 'foo';
$scope.bar = 'bar';
$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
// newValues array contains the current values of the watch expressions
// with the indexes matching those of the watchExpression array
// i.e.
// newValues[0] -> $scope.foo
// and
// newValues[1] -> $scope.bar
});
La différence est que vous pouvez utiliser un véritable tableau au lieu d'une chaîne qui ressemble à un tableau.
J'ai eu un problème similaire mais en utilisant le motif controllerAs. Dans mon cas, la solution consistait à ajouter aux variables le nom du contrôleur : $scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
À partir d'AngularJS 1.1.4 vous pouvez utiliser $watchCollection
:
$scope.$watchCollection('[item1, item2]', function(newValues, oldValues){
// do stuff here
// newValues and oldValues contain the new and respectively old value
// of the observed collection array
});
Exemple de Plunker aquí
Documentation aquí
Notez que le premier paramètre est no un tableau. C'est une chaîne qui ressemble à un tableau.
Merci pour cela. si cela fonctionne pour moi, je vous donnerai mille pièces d'or - virtuelles, bien sûr :)
Pour être clair (il m'a fallu quelques minutes pour le réaliser) $watchCollection
est destiné à recevoir un objet et à surveiller les changements apportés aux propriétés de l'objet, alors que $watchGroup
est destiné à fournir un tableau de propriétés individuelles à surveiller pour les changements. Légèrement différent pour aborder des problèmes similaires mais différents. Ouf !
$watch
Le premier paramètre peut également être une fonction.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Si vos deux valeurs combinées sont simples, le premier paramètre est juste une expression angulaire normalement. Par exemple, firstName et lastName :
$scope.$watch('firstName + lastName', function() {
//stuff
});
Il s'agit d'un cas d'utilisation qui mérite d'être inclus par défaut dans le cadre de travail. Même une propriété calculée aussi simple que fullName = firstName + " " + lastName
nécessite de passer une fonction comme premier argument (plutôt qu'une simple expression comme 'firstName, lastName'
). Angular est TELLEMENT puissant, mais il y a certains domaines où il peut être énormément plus convivial pour les développeurs d'une manière qui ne compromet pas (semble-t-il) les performances ou les principes de conception.
Eh bien $watch prend juste une expression angulaire, qui est évaluée sur la portée sur laquelle elle est appelée. Donc vous pourriez faire $scope.$watch('firstName + lastName', function() {...})
. Vous pourriez aussi faire deux montres : function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. J'ai ajouté le cas simple à la réponse.
Le plus dans 'firstName + lastName' est une concaténation de chaînes de caractères. Angular vérifie donc simplement si le résultat de la concaténation est différent maintenant.
Voici une solution très similaire à votre pseudo-code original qui fonctionne réellement :
$scope.$watch('[item1, item2] | json', function () { });
EDIT : Ok, je pense que c'est encore mieux :
$scope.$watch('[item1, item2]', function () { }, true);
En gros, nous sautons l'étape du json, ce qui semblait stupide au départ, mais ça ne marchait pas sans. La clé est le 3ème paramètre souvent omis qui active l'égalité des objets par opposition à l'égalité des références. Ainsi, les comparaisons entre les objets de notre tableau créé fonctionnent correctement.
Les deux ont un léger surcoût de performance si les éléments dans l'expression du tableau ne sont pas des types simples.
C'est vrai il fait une comparaison approfondie des objets composants. Ce qui n'est pas forcément ce que vous voulez. Voir la réponse actuellement approuvée pour une version utilisant angular moderne qui ne fait pas de comparaison en profondeur.
Pourquoi ne pas simplement l'envelopper dans un forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
C'est à peu près la même surcharge que de fournir une fonction pour la valeur combinée, sans avoir à se soucier de la composition de la valeur .
Dans ce cas, log() serait exécuté plusieurs fois, n'est-ce pas ? Je pense que dans le cas de fonctions $watch imbriquées, ce ne serait pas le cas. Et il ne devrait pas dans la solution pour surveiller plusieurs attributs à la fois.
Non, le journal n'est exécuté qu'une fois par changement et par propriété surveillée. Pourquoi serait-il invoqué plusieurs fois ?
C'est vrai, je veux dire que ça ne marcherait pas bien si on voulait tous les regarder simultanément.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.