Ответы:
Начиная с AngularJS 1.3, появился новый метод $watchGroup
для наблюдения за набором выражений.
$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
и oldValues
как undefined
, а индивидуальный просмотр свойств работает как обычно.
Начиная с AngularJS 1.1.4 вы можете использовать $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
});
Пример плунжера здесь
Документация здесь
$watchCollection
, предназначено для передачи объекта и обеспечения отслеживания изменений любых свойств объекта, в то время $watchGroup
как предназначено для передачи массива отдельных свойств для отслеживания изменений. Немного отличается, чтобы решать похожие, но разные проблемы. Уф!
$watch
Первый параметр также может быть функцией.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Если ваши два объединенных значения просты, первый параметр обычно является угловым выражением. Например, firstName и lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
требует передачи функции в качестве первого аргумента (а не простого выражения типа 'firstName, lastName'
). Angular настолько мощен, но есть некоторые области, где он может быть гораздо более дружественным к разработчикам способами, которые (как представляется) не ставят под угрозу производительность или принципы проектирования.
$scope.$watch('firstName + lastName', function() {...})
. Вы можете просто сделать два часы: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Я добавил простой случай к ответу.
Вот решение, очень похожее на ваш оригинальный псевдокод, который действительно работает:
$scope.$watch('[item1, item2] | json', function () { });
РЕДАКТИРОВАТЬ: Хорошо, я думаю, что это даже лучше:
$scope.$watch('[item1, item2]', function () { }, true);
По сути, мы пропускаем шаг json, который казался глупым с самого начала, но без этого он не работал. Их ключ - часто пропускаемый 3-й параметр, который включает равенство объектов, а не равенство ссылок. Тогда сравнения между нашими созданными объектами массива действительно работают правильно.
TypeError: Object #<Object> has no method '$watchCollection'
но это решение помогает мне решить мою проблему!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Вы можете использовать функции в $ watchGroup для выбора полей объекта в области видимости.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? Разве область не распространяется на функции без явного ее определения?
Почему бы просто не обернуть его в forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Это примерно такая же нагрузка, как и предоставление функции для объединенного значения, без необходимости беспокоиться о составе значения .
changed()
вызывается всякий раз, когда что-то изменяется в любом из свойств. Это точно такое же поведение, как если бы была предоставлена функция для комбинированного значения.
Несколько более безопасным решением для объединения значений может быть использование следующего в качестве вашей $watch
функции:
function() { return angular.toJson([item1, item2]) }
или
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
Параметр $ watch first может быть угловым выражением или функцией. Смотрите документацию по $ scope. $ Watch . Он содержит много полезной информации о том, как работает метод $ watch: когда вызывается watchExpression, как angular сравнивает результаты и т. Д.
как насчет:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
параметра to scope.$watch
(как в вашем примере) он listener()
будет срабатывать каждый раз, потому что анонимный хэш имеет разную ссылку каждый раз.
return { a: functionA(), b: functionB(), ... }
. Затем я проверяю возвращенные объекты новых и старых значений друг против друга.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Здесь функция будет вызываться при изменении значения возраста и имени.
Angular, представленный $watchGroup
в версии 1.3, с помощью которого мы можем наблюдать несколько переменных, причем один $watchGroup
блок
$watchGroup
принимает массив в качестве первого параметра, в который мы можем включить все наши переменные для просмотра.
$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]);
});