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.