Angular watch,digest and apply function
Posted By : Deepak Gupta | 22-Dec-2014
Angular watch,digest and apply function
$watch
AngularJS offers feature known two way data binding Data binding means that when you change something in the view, the scope model automatically updates. Similarly, whenever the scope model changes, the view updates itself with the new value Whenever you create a data binding in angular js on the scope object on view, then it create a watch internally on that object. Watch means angular js watches change on that scope object Watches are created by calling $scope.watch() on that.
When you register or create watch function then it take two paramter in function. First paramter is value function second paramter is associated listener Here is an example -
$scope.$watch(function() {},
function() {}
);
The value function should return the value which is being watched When the return function is changed to previous one then angularJs would call the corresponding listener.
$scope.$watch(function(scope) { return scope.data.myVar },
function() {}
);
Notice Please notice how return function takes scope(without $ parameter) as parameter this scope refer to the $scope object. Now you can pass a string in place of value function like this-
$scope.$watch('foo', function(newVal, oldVal) {
console.log(newVal, oldVal);
});
If you pass an expression (a string), it will be evaluated against $scope and converted to a function to be watched. If you pass a function, it just watches that function, with no conversion necessary.
The listener function should do whatever it needs to do if the value has changed. Here is code in listener function.
$scope.$watch(function(scope) { return scope.data.myVar },
function(newValue, oldValue) {
document.getElementById("").innerHTML =
"" + newValue + "";
}
);
The previous example just set HTML DOM element Of course you could have done this using the code {{ data.myVar }, but this is just an example of what you can do inside the listener function.
Now its time to ask question how angularjs figure out when to call listener function mean how it know that value is changed or not Does angular js periodically call a function to examine value is change or not Well , its true secret behind that is digest cycle.
Digest Cycle
Digest cycle is where the watchers are fired. When a watcher is fired, AngularJS evaluates the scope model, and if it has changed then the corresponding listener function is called.
$digest
When digest cycle start it start start with a call to $scope.digest() Assume you want to change a scope value through ng-click on button .Then AngularJs call start digest cycle by calling digest function. When cycle start then it fires all watcher's and these watchers check whether current value is changed from the previous one. If yes then it call the corresponding listener function . As a result if you have any expression in your view then it will be updated.
Digest function is called by AngularJs whenever it is neccessary It would be after a fucntiona call or ajax call or a table upadte.
You may found in some cases where AngularJS does not call the $digest() function for you So you can explicitly call scope.$digest() and it should work. Or, you can perhaps use $scope.$apply() .
$apply()
From above explanation there is a some gotcha Angular doesnot directly call digest() function. Instead it first call apply() function which in turn then it call $rootscope.digest(). As a result it will start digest cycle on all child scope along calling watch function .
Now let say you have called a function on ng-click on button click then angularJs wrap this function within $scope.apply().So, your function executes as usual, change models (if any), and a $digest cycle starts to ensure your changes are reflected in the view.
Note $scope.apply() function internally calls $rootscope.digest() function .
The apply function calls in two way-
1. first it take function as argument then evalute that function and triggers digest function
2. you can simply call $scope.digest()
Angularjs makes one thing clear It will work for only those model changes which are done inside AngularJS’ context. Angular js directive already does this. If you want to inform any outside angular context model changes then you have explicitly call $scope.apply() function.
When you call apply function then you should call parameter's apply function mean you should call version of $apply() function which take function as parameter because when you pass a function as parameter then the function call is wrapped inside a try...catch block, and any exceptions that occur will be passed to the $exceptionHandler service.
I hope this blog would help you to understand $apply and $diges function And the important this is that if angular js does not change your model you shoould call apply function manually.
THANKS
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Deepak Gupta
Deepak is a bright Groovy and Grails developer