Max Koretskyi
Max Koretskyi

Reputation: 105439

$watch API description - first function described as listener function, why?

I'm reading through documentation on scope's method $watch here. The method accepts: $watch(watchExpression, [listener]; Then they provide examples:

// let's assume that scope was dependency injected as the $rootScope
var scope = $rootScope;
scope.name = 'misko';
scope.counter = 0;

expect(scope.counter).toEqual(0);
scope.$watch('name', function(newValue, oldValue) {
 scope.counter = scope.counter + 1;
});
expect(scope.counter).toEqual(0);

scope.$digest();
// the listener is always called during the first $digest loop after it was registered
expect(scope.counter).toEqual(1);

scope.$digest();
// but now it will not be called unless the value changes
expect(scope.counter).toEqual(1);

scope.name = 'adam';
scope.$digest();
expect(scope.counter).toEqual(2);



// Using a listener function
var food;
scope.foodCounter = 0;
expect(scope.foodCounter).toEqual(0);
scope.$watch(
 // This is the listener function --------- WHY ?????????????
 function() { return food; },
 // This is the change handler ---- THIS SHOULD BE A LISTNER FUNCTION
 function(newValue, oldValue) {
   if ( newValue !== oldValue ) {
     // Only increment the counter if the value changed
     scope.foodCounter = scope.foodCounter + 1;
   }
 }
);
// No digest has been run so the counter will be zero
expect(scope.foodCounter).toEqual(0);

// Run the digest but since food has not changed count will still be zero
scope.$digest();
expect(scope.foodCounter).toEqual(0);

// Update food and run digest.  Now the counter will increment
food = 'cheeseburger';
scope.$digest();
expect(scope.foodCounter).toEqual(1);

What I don't understand is that why they refer to function() { return food; } in the second example as a // This is the listener function if this is the function that should return the value that will be watched. which is a watchExpression?

Upvotes: 1

Views: 598

Answers (1)

jantimon
jantimon

Reputation: 38142

The comment is a little bit misleading and you might file an issue or pull request to improve it.

As you said correctly there are 2 arguments for $watch(watchExpression, [listener])

  • watchExpression
    The watchExpression is called on every call to $digest() and should return the value that will be watched.
    The watch expression can be either a string or a function. If you specify a function this is not the listener but rather a comparison function which will be called many many times so don't do any fancy stuff here ;)
    This comparison function is used for the angular dirty checking.
    More details on this can be found in this part of the video by the creator of angularJs: https://www.youtube.com/watch?feature=player_detailpage&v=ZhfUv0spHCY#t=1988

  • listener
    This function is called whenever the value of your watchExpression changes.
    So this a perfect place to update your models and do your fancy business logic

Upvotes: 1

Related Questions