Просмотр нескольких атрибутов $scope

Есть ли способ подписаться на события на нескольких объектах, используя $watch

например.

$scope.$watch('item1, item2', function () { });

Ответ 1

Начиная с 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 
});

Ответ 2

Начиная с 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
});

Пример плунжера здесь

Документация здесь

Ответ 3

$watch Первый параметр также может быть функцией.

$scope.$watch(function watchBothItems() {
  return itemsCombinedValue();
}, function whenItemsChange() {
  //stuff
});

Если ваши два комбинированных значения просты, первый параметр - это просто выражение angular. Например, firstName и lastName:

$scope.$watch('firstName + lastName', function() {
  //stuff
});

Ответ 4

Вот решение, очень похожее на ваш оригинальный псевдокод, который действительно работает:

$scope.$watch('[item1, item2] | json', function () { });

EDIT: Хорошо, я думаю, что это еще лучше:

$scope.$watch('[item1, item2]', function () { }, true);

В основном мы пропустим шаг json, который казался глупым, но он не работал без него. Они являются часто отсутствующим 3-м параметром, который включает в себя равенство объектов, а не ссылочное равенство. Тогда сравнения между нашими созданными объектами массива действительно работают правильно.

Ответ 5

Почему бы просто не обернуть его в forEach?

angular.forEach(['a', 'b', 'c'], function (key) {
  scope.$watch(key, function (v) {
    changed();
  });
});

Это примерно такая же накладная задача, как предоставление функции для комбинированного значения без необходимости беспокоиться о композиции значений.

Ответ 6

Вы можете использовать функции в $watchGroup для выбора полей объекта в области.

        $scope.$watchGroup(
        [function () { return _this.$scope.ViewModel.Monitor1Scale; },   
         function () { return _this.$scope.ViewModel.Monitor2Scale; }],  
         function (newVal, oldVal, scope) 
         {
             if (newVal != oldVal) {
                 _this.updateMonitorScales();
             }
         });

Ответ 7

Несколько более безопасное решение для объединения значений может заключаться в использовании следующих функций $watch:

function() { return angular.toJson([item1, item2]) }

или

$scope.$watch(
  function() {
    return angular.toJson([item1, item2]);
  },
  function() {
    // Stuff to do after either value changes
  });

Ответ 8

$Первым параметром watch может быть angular выражение или функция. См. Документацию по $scope. $Watch. Он содержит много полезной информации о том, как работает метод $watch: когда вызывается watchExpression, как angular сравнивает результаты и т.д.

Ответ 9

как насчет:

scope.$watch(function() { 
   return { 
      a: thing-one, 
      b: thing-two, 
      c: red-fish, 
      d: blue-fish 
   }; 
}, listener...);

Ответ 10

$scope.$watch('age + name', function () {
  //called when name or age changed
});

Здесь функция будет вызвана, когда изменится значение возраста и имени.