Wednesday, May 28, 2014

AngularJs and $scope.$apply - When and How to use $apply for AngularJs scope

In this blog I will explain when to use $apply for AngularJs $scope and how to use it. You may have encountered the situation where you update the variables bind to AngularJs view but it does not update views. So here I will explain why it happens and how to resolve it. Also you need to know how to use $apply carefully else it may give you error that $apply is already in progress.

First lets understand how the AngularJs data binding works.AngularJs framework monitors data changes with the digest cycles. That means it checks it frequently in digest cycle then framework will be notified if you have made any changes in managed code. But there are chances that you have some external events like Ajax callbacks or some native click events. These event runs outside the scope of AngularJs digest cycles. So the framework does not know about any changes made during this events. You have to tell the framework that there are changes. Here $apply comes to the picture. It lets you start digest cycle explicitly. So that your frameworks knows that there are changes. Lets assume that you have variable $scope.myVar and you changed its value in native click event. So you need to tell Framework that it is changed. So if you simply use,

$scope.myVar = 'New Value';

It will not work. Instead of this you have to use

      $scope.myVar = 'New Value';

or you can use this syntax.

$scope.myVar = 'New Value';

This shall notify the framework that the value is changed. It's not always safe to use $apply as I mentioned earlier. If the digest cycle is already in progress and you try to set it and with $apply it will give you an error. So if you have condition like your variable is updated at common function which you calls from AngularJs managed code and outside events. you have to first check it digest cycle is already in progress. If not then only use $apply. You can check it with following code.

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
       $scope.myVar = 'New Value';

This will be the safe apply and it will not give you any error .

No comments:

Post a Comment