Antworten:
Ab AngularJS 1.3 gibt es eine neue Methode $watchGroup
zum Beobachten einer Reihe von Ausdrücken.
$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
und oldValues
als ausgeführt wird undefined
, während die Eigenschaften einzeln wie gewohnt funktionieren.
Ab AngularJS 1.1.4 können Sie Folgendes verwenden $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
});
Plunker Beispiel hier
Dokumentation hier
$watchCollection
, soll ein Objekt übergeben werden und eine Überwachung für Änderungen an den Eigenschaften des Objekts bereitstellen, während $watchGroup
eine Reihe von einzelnen Eigenschaften übergeben werden soll, um auf Änderungen zu achten. Etwas anders, um ähnliche, aber unterschiedliche Probleme anzugehen. Puh!
$watch
Der erste Parameter kann auch eine Funktion sein.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Wenn Ihre beiden kombinierten Werte einfach sind, ist der erste Parameter normalerweise nur ein Winkelausdruck. Zum Beispiel Vorname und Nachname:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
erfordert die Übergabe einer Funktion als erstes Argument (anstelle eines einfachen Ausdrucks wie 'firstName, lastName'
). Angular ist SO leistungsfähig, aber es gibt einige Bereiche, in denen es auf eine Weise, die die Leistung oder die Designprinzipien nicht beeinträchtigt (scheinbar), erheblich entwicklerfreundlicher sein kann.
$scope.$watch('firstName + lastName', function() {...})
. Sie könnten auch nur zwei Uhren machen : function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Ich habe der Antwort den einfachen Fall hinzugefügt.
Hier ist eine Lösung, die Ihrem ursprünglichen Pseudocode sehr ähnlich ist und tatsächlich funktioniert:
$scope.$watch('[item1, item2] | json', function () { });
EDIT: Okay, ich denke das ist noch besser:
$scope.$watch('[item1, item2]', function () { }, true);
Grundsätzlich überspringen wir den JSON-Schritt, der anfangs dumm schien, aber ohne ihn nicht funktioniert hat. Der Schlüssel ist der häufig ausgelassene dritte Parameter, der die Objektgleichheit im Gegensatz zur Referenzgleichheit aktiviert. Dann funktionieren die Vergleiche zwischen unseren erstellten Array-Objekten tatsächlich richtig.
TypeError: Object #<Object> has no method '$watchCollection'
aber diese Lösung hilft mir, mein Problem zu lösen!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Sie können Funktionen in $ watchGroup verwenden, um Felder eines Objekts im Bereich auszuwählen.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? Wird der Bereich nicht in die Funktionen übernommen, ohne ihn explizit zu definieren?
Warum nicht einfach einpacken forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Es ist ungefähr der gleiche Aufwand wie das Bereitstellen einer Funktion für den kombinierten Wert, ohne sich um die Wertzusammensetzung kümmern zu müssen .
changed()
wird immer dann aufgerufen, wenn sich in einer der Eigenschaften etwas ändert. Das ist genau das gleiche Verhalten, als ob eine Funktion für den kombinierten Wert bereitgestellt worden wäre.
Eine etwas sicherere Lösung zum Kombinieren von Werten könnte darin bestehen, Folgendes als $watch
Funktion zu verwenden:
function() { return angular.toJson([item1, item2]) }
oder
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
Der Parameter $ watch first kann ein Winkelausdruck oder eine Funktion sein. Siehe Dokumentation zu $ scope. $ Watch . Es enthält viele nützliche Informationen zur Funktionsweise der $ watch-Methode: Wenn watchExpression aufgerufen wird, wie eckig die Ergebnisse verglichen werden usw.
wie wäre es mit:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
Parameter to to scope.$watch
(wie in Ihrem Beispiel) listener()
würde jedes Mal ausgelöst, da der anonyme Hash jedes Mal eine andere Referenz hat.
return { a: functionA(), b: functionB(), ... }
. Ich überprüfe dann die zurückgegebenen Objekte der neuen und alten Werte gegeneinander.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Hier wird die Funktion aufgerufen, wenn sowohl Alter als auch Namenswert geändert werden.
$watchGroup
In Version 1.3 eingeführter Winkel, mit dem wir mehrere Variablen überwachen können, wobei ein einzelner $watchGroup
Block
$watchGroup
das Array als ersten Parameter verwendet, in den wir alle zu überwachenden Variablen aufnehmen können.
$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]);
});