Monday, 29 January 2018

AngularJS –Access Scope from outside function ($apply)

We know angularjs has a data binding between scope and html, which means what ever data changes we make in our controller scope it gets reflected to our html. But things change when we use a 3rd party library or external events to make changes to our scope.

Lets take an example to see how this happens

HTML
<body ng-app='MainApp'>
    <div ng-controller='MainCtrl'>
      <div>
        <div>{{text}}</div>
        <button id='click_button' type='button' >Click Me</button>
        <p>When You Click, only alert shows but text doesn't update</p>
      </div>
    </div>
</body>

ANGULARJS
var mainMod = angular.module('MainApp', []);
mainMod.controller('MainCtrl', ['$scope',
    function ($scope) {
         
         $scope.text = 'Hey';
         $('#click_button').click(function(){
           alert('Click!');
           $scope.text = new Date();
         });
    }
]);

In the above, code I have taken a simple scope variable “text” and used jquery library to demonstrate an outside function. So using jquery’s click function, when you click on the “Click Me” button i have changed the scope “text” variable to current date. If you run the code you will see that it will not work.

Access Angular Scope From Outside Function or 3rd Party Library
AngularJS exposes a method “$apply” for this purpose. This function is used to inform angular that changes have been made to $scope variable from an outside function or event.

Here is code for the same

ANGULARJS
var mainMod = angular.module('MainApp', []);
mainMod.controller('MainCtrl', ['$scope',
    function ($scope) {
         
         $scope.text = 'Hey';
         $('#click_button').click(function(){
           alert('Click!');
           $scope.$apply(function(){
             $scope.text = new Date();
           });
         });
    }
]);

Now we see Date gets updated on button click.
The only change made to above code was

$scope.$apply(function(){
  $scope.text = new Date();
});

So we made the $scope changes inside the $apply function. This tell answer to run the $digest cycle to check for any changes in $scope.

Difference Between $apply and $apply(fn)

There are two ways to use the $apply function, taking the above example

 Method1:

$scope.$apply(function(){
             $scope.text = new Date();
           });

Method2:

$scope.text = new Date();
$scope.$apply();

In most cases both the above will give you the same desired effect, but there are difference between the two. As per angular documentation, pseduo code for $apply is

function $apply(expr) {
  try {
    return $eval(expr);
  catch (e) {
    $exceptionHandler(e);
  } finally {
    $root.$digest();
  }
}

So the Method1 takes care of exception handling and always run the digest cycle. So method1 is always preferred to method2.

   

1 comment:

Topics

ADO .Net (2) Ajax (1) Angular Js (17) Angular2 (24) ASP .Net (14) Azure (1) Breeze.js (1) C# (49) CloudComputing (1) CMS (1) CSS (2) Design_Pattern (3) DI (3) Dotnet (21) Entity Framework (3) ExpressJS (4) Html (3) IIS (1) Javascript (6) Jquery (9) Lamda (3) Linq (11) Mongodb (1) MVC (48) NodeJS (7) RDLC (1) Report (1) Sql Server (29) SSIS (3) SSRS (2) UI (1) WCF (12) Web Api (9) Web Service (1) XMl (1)