Regarder plusieurs attributs de portée $

Existe-t-il un moyen de s'abonner à des événements sur plusieurs objets en utilisant $watch

Par exemple

 $scope.$watch('item1, item2', function () { }); 

À partir de AngularJS 1.3, il existe une nouvelle méthode appelée $watchGroup pour observer 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 // ie // newValues[0] -> $scope.foo // and // newValues[1] -> $scope.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 ici

Documentation ici

$watch 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 }); 

Voici une solution très similaire à votre pseudo-code original qui fonctionne réellement:

 $scope.$watch('[item1, item2] | json', function () { }); 

EDIT: D'accord, je pense que c'est encore mieux:

 $scope.$watch('[item1, item2]', function () { }, true); 

Fondamentalement, nous ignorons le json, ce qui semblait stupide pour commencer, mais cela ne fonctionnait pas sans cela. Ils sont le paramètre 3 souvent omis qui active l'égalité des objets par rapport à l'égalité de référence. Ensuite, les comparaisons entre nos objets de matrice créés fonctionnent correctement.

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 le même frais généraux que de fournir une fonction pour la valeur combinée, sans devoir s'inquiéter de la composition de la valeur .

Une solution légèrement plus sûre pour combiner les valeurs pourrait être d'utiliser comme suit:

 function() { return angular.toJson([item1, item2]) } 

ou

 $scope.$watch( function() { return angular.toJson([item1, item2]); }, function() { // Stuff to do after either value changes }); 

Vous pouvez utiliser des fonctions dans $ watchGroup pour sélectionner les champs d'un objet dans la portée.

  $scope.$watchGroup( [function () { return _this.$scope.ViewModel.Monitor1Scale; }, function () { return _this.$scope.ViewModel.Monitor2Scale; }], function (newVal, oldVal, scope) { if (newVal != oldVal) { _this.updateMonitorScales(); } }); 

$ Regarder le premier paramètre peut être une expression ou une fonction angulaire . Voir la documentation sur $ scope. $ Watch . Il contient beaucoup d'informations utiles sur la façon dont la méthode $ watch fonctionne: lorsque WatchExpression s'appelle, comment angular compare les résultats, etc.

que diriez-vous:

 scope.$watch(function() { return { a: thing-one, b: thing-two, c: red-fish, d: blue-fish }; }, listener...); 
 $scope.$watch('age + name', function () { //called when name or age changed }); 

La fonction sera alors appelée lorsque l'âge et la valeur du nom seront modifiés.