Est-il possible de s'abonner à des événements sur plusieurs objets à l'aide de $watch
Par exemple.
$scope.$watch('item1, item2', function () { });
Depuis 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
});
_
À partir de 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
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 simplement une expression angular. Par exemple, firstName et lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
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);
En gros, nous sautons l’étape JSON, qui semblait stupide au départ, mais elle ne fonctionnait pas sans elle. Leur clé est le troisième paramètre souvent omis qui active l'égalité des objets par opposition à l'égalité des références. Ensuite, les comparaisons entre nos objets de tableau créés fonctionnent réellement.
Vous pouvez utiliser les fonctions de $ 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();
}
});
Pourquoi ne pas simplement envelopper dans un forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Cela revient à peu près au même coût que fournir une fonction pour la valeur combinée, sans avoir à se soucier de la composition de la valeur.
Une solution légèrement plus sûre pour combiner des valeurs peut être d'utiliser les éléments suivants comme fonction $watch
:
function() { return angular.toJson([item1, item2]) }
ou
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
Le premier paramètre de $ watch peut être expression angulaire ou fonction. Voir la documentation sur $ scope. $ Watch . Il contient de nombreuses informations utiles sur le fonctionnement de la méthode $ watch: quand appeler watchExpression, 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
});
Ici, la fonction sera appelée lorsque l'âge et le nom auront été modifiés.
Angular a introduit $watchGroup
dans la version 1.3 en utilisant laquelle nous pouvons regarder plusieurs variables, avec un seul $watchGroup
block $watchGroup
prend un tableau comme premier paramètre dans lequel nous pouvons inclure toutes nos variables à surveiller.
$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]);
});