Watch multiple $scope attributes

191,956

Solution 1

Starting from AngularJS 1.3 there's a new method called $watchGroup for observing a set of 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 
});

Solution 2

Beginning with AngularJS 1.1.4 you can use $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 example here

Documentation here

Solution 3

$watch first parameter can also be a function.

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

If your two combined values are simple, the first parameter is just an angular expression normally. For example, firstName and lastName:

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

Solution 4

Here's a solution very similar to your original pseudo-code that actually works:

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

EDIT: Okay, I think this is even better:

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

Basically we're skipping the json step, which seemed dumb to begin with, but it wasn't working without it. They key is the often omitted 3rd parameter which turns on object equality as opposed to reference equality. Then the comparisons between our created array objects actually work right.

Solution 5

You can use functions in $watchGroup to select fields of an object in scope.

        $scope.$watchGroup(
        [function () { return _this.$scope.ViewModel.Monitor1Scale; },   
         function () { return _this.$scope.ViewModel.Monitor2Scale; }],  
         function (newVal, oldVal, scope) 
         {
             if (newVal != oldVal) {
                 _this.updateMonitorScales();
             }
         });
Share:
191,956
Greg
Author by

Greg

Blaze UI - Open Source Modular UI Toolkit

Updated on August 24, 2022

Comments

  • Greg
    Greg over 1 year

    Is there a way to subscribe to events on multiple objects using $watch

    E.g.

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