Réponses:
À partir d'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
// i.e.
// newValues[0] -> $scope.foo
// and
// newValues[1] -> $scope.bar
});
$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
newValues
et oldValues
as undefined
, tout en regardant individuellement les propriétés fonctionner comme d'habitude.
À 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 Plunker ici
Documentation ici
$watchCollection
est prévu de remettre un objet et de surveiller les modifications de l'une des propriétés de l'objet, alors qu'il $watchGroup
est destiné à recevoir un tableau de propriétés individuelles pour surveiller les modifications. Légèrement différent pour s'attaquer à des problèmes similaires mais différents. Phew!
$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 n'est normalement qu'une expression angulaire. Par exemple, firstName et lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
nécessite de passer une fonction comme premier argument (plutôt qu'une simple expression comme 'firstName, lastName'
). Angular est SI 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 semble pas compromettre les performances ou les principes de conception.
$scope.$watch('firstName + lastName', function() {...})
. Vous pouvez aussi simplement faire deux montres: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. J'ai ajouté le cas simple à la réponse.
Voici une solution très similaire à votre pseudo-code d'origine 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 sautons l'étape json, qui semblait stupide au début, mais cela ne fonctionnait pas sans elle. Leur clé est le 3e paramètre souvent omis qui active l'égalité d'objet par opposition à l'égalité de référence. Ensuite, les comparaisons entre nos objets de tableau créés fonctionnent correctement.
TypeError: Object #<Object> has no method '$watchCollection'
mais cette solution m'aide à résoudre mon problème!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Vous pouvez utiliser des fonctions dans $ watchGroup pour sélectionner des 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();
}
});
_this
? La portée n'est-elle pas portée dans les fonctions sans la définir explicitement?
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 chose que de fournir une fonction pour la valeur combinée, sans avoir à se soucier de la composition de la valeur .
changed()
est invoqué chaque fois que quelque chose change dans l'une des propriétés. C'est exactement le même comportement que si une fonction pour la valeur combinée était fournie.
Une solution légèrement plus sûre pour combiner des valeurs pourrait être d'utiliser la fonction suivante comme $watch
fonction:
function() { return angular.toJson([item1, item2]) }
ou
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
Le paramètre $ watch first peut être une expression ou une fonction angulaire . Voir la documentation sur $ scope. $ Watch . Il contient de nombreuses informations utiles sur le fonctionnement de la méthode $ watch: lorsque watchExpression est appelée, comment angulaire 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...);
true
paramètre to scope.$watch
(comme dans votre exemple), listener()
se déclencherait à chaque fois, car le hachage anonyme a une référence différente à chaque fois.
return { a: functionA(), b: functionB(), ... }
. Je vérifie ensuite les objets retournés des nouvelles et anciennes valeurs les uns par rapport aux autres.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Ici, la fonction sera appelée lorsque l'âge et la valeur du nom seront modifiés.
Angular introduit $watchGroup
dans la version 1.3 à l'aide duquel nous pouvons regarder plusieurs variables, avec un seul $watchGroup
bloc
$watchGroup
prend le tableau comme premier paramètre dans lequel nous pouvons inclure toutes nos variables à regarder.
$scope.$watchGroup(['var1','var2'],function(newVals,oldVals){
console.log("new value of var1 = " newVals[0]);
console.log("new value of var2 = " newVals[1]);
console.log("old value of var1 = " oldVals[0]);
console.log("old value of var2 = " oldVals[1]);
});