Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does angularjs set watcher for functions?

I understand that when I have <p>{{abc}}<p> or {{ng-repeat="item in list"}} angularjs will set watcher for $scope.abc and $scope.list, thus their value will be checked during every digest loop.

However when I am using ng-class directive with a function, I could not figure out what expression is angular watching

angular.module("app",[]).controller("control",function($scope){
  var clicked = false;   
  // this is the variable I would watch for and returnString is the call back...
  // but how could angular possibly know??
  $scope.toggle = function(){
    clicked = !clicked;
  }
  $scope.returnString = function(){
    if(clicked){
      return 'text-success';
    }
    return 'text-danger';
  }
});
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link data-require="[email protected]" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    <script data-require="[email protected]" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
  </head>

  <body ng-controller="control">
    <button ng-click="toggle()">click</button>
    <h1 ng-class="returnString()">hello world</h1>
    <!--ng-class="clicked?'text-success':'text-danger'" this way angular knows what to watch...but what if I give it a function???-->
  </body>

</html>

in the html...angular does not know what value "returnString()" relys on, how could the framework set a watcher? or does angular simply run ng-class expression after every digest loop?

like image 831
watashiSHUN Avatar asked Jan 17 '26 22:01

watashiSHUN


1 Answers

AngularJs can use $watch over a function too.

For instance, instead of $watch('abc', function() { /* code */});

you could do this

$watch(function() { return $scope.$abc; }, function() { /* code */ });

so ng-class works on the same way: if you place a function, it will apply a $watch to the function in the scope context (this meaning the function needs to be defined in the current scope)

See $watch documentation in AngularDocs of how it uses a function to watch:

scope.$watch(
  // This function returns the value being watched. It is called for each turn of the $digest loop
  function() { return food; },
  // This is the change listener, called when the value returned from the above function changes
  function(newValue, oldValue) {
    if ( newValue !== oldValue ) {
      // Only increment the counter if the value changed
      scope.foodCounter = scope.foodCounter + 1;
    }
  }
);

The thing being watched, then, is the result of the function, which is executed in every digest loop (you can set a debug breakpoint to verify it)

like image 63
Gonzalo.- Avatar answered Jan 19 '26 20:01

Gonzalo.-