Odpowiedzi:
Począwszy od AngularJS 1.3 istnieje nowa metoda wywołana $watchGroup
do obserwowania zestawu wyrażeń.
$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
i oldValues
as undefined
, podczas indywidualnego oglądania właściwości działają jak zwykle.
Począwszy od AngularJS 1.1.4 możesz używać $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
});
Przykład plunkera tutaj
Dokumentacja tutaj
$watchCollection
ma na celu przekazanie obiektu i obserwowanie zmian w dowolnych właściwościach obiektu, podczas gdy w $watchGroup
zamierzeniu ma być przekazany szereg indywidualnych właściwości do obserwowania zmian. Nieco inaczej, aby rozwiązać podobne, ale różne problemy. Uff!
$watch
Pierwszy parametr może być również funkcją.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Jeśli dwie połączone wartości są proste, pierwszy parametr jest normalnie wyrażeniem kątowym. Na przykład firstName i lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
wymaga przekazania funkcji jako pierwszego argumentu (zamiast prostego wyrażenia, takiego jak 'firstName, lastName'
). Angular jest tak potężny, ale jest kilka obszarów, w których może być niezwykle przyjazny dla programistów w sposób, który (nie wydaje się) narażać na szwank wydajności lub zasad projektowania.
$scope.$watch('firstName + lastName', function() {...})
. Można też po prostu zrobić dwa zegarki: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Do odpowiedzi dodałem prosty przypadek.
Oto rozwiązanie bardzo podobne do oryginalnego pseudokodu, które faktycznie działa:
$scope.$watch('[item1, item2] | json', function () { });
EDYCJA: OK, myślę, że jest jeszcze lepiej:
$scope.$watch('[item1, item2]', function () { }, true);
Zasadniczo pomijamy krok Jsona, co na początku wydawało się głupie, ale bez niego nie działałoby. Klucz to często pomijany trzeci parametr, który włącza równość obiektów w przeciwieństwie do równości odniesienia. Wtedy porównania między naszymi utworzonymi obiektami tablicowymi faktycznie działają poprawnie.
TypeError: Object #<Object> has no method '$watchCollection'
ale to rozwiązanie pomaga mi rozwiązać mój problem!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Możesz użyć funkcji w $ watchGroup, aby wybrać pola obiektu w zakresie.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? Czy zakres nie jest przenoszony do funkcji bez wyraźnego zdefiniowania go?
Dlaczego nie po prostu owinąć to w forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
To mniej więcej tyle samo, co zapewnienie funkcji dla połączonej wartości, bez faktycznego martwienia się o skład wartości .
changed()
jest wywoływany za każdym razem, gdy coś zmienia się w którejkolwiek z właściwości. To jest dokładnie to samo zachowanie, jakby podano funkcję dla połączonej wartości.
Pierwszy parametr $ watch może być wyrażeniem kątowym lub funkcją. Zobacz dokumentację dotyczącą $ scope. $ Watch . Zawiera wiele użytecznych informacji o tym, jak działa metoda $ watch: kiedy wywoływana jest funkcja watchExpression, sposób porównywania wyników przez kąt itp.
Co powiesz na:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
parametru to scope.$watch
(jak w twoim przykładzie) listener()
uruchamiany byłby za każdym razem, ponieważ anonimowy skrót ma za każdym razem inne odniesienie.
return { a: functionA(), b: functionB(), ... }
. Następnie sprawdzam względem siebie zwrócone obiekty nowych i starych wartości.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Tutaj funkcja zostanie wywołana, gdy zmieni się zarówno wiek, jak i imię.
Angular wprowadzony $watchGroup
w wersji 1.3, za pomocą którego możemy oglądać wiele zmiennych, z jednym $watchGroup
blokiem
$watchGroup
przyjmuje tablicę jako pierwszy parametr, w którym możemy uwzględnić wszystkie nasze zmienne do oglądania.
$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]);
});