简体   繁体   中英

Why directly not able to call a function from `controller` in `AngularJs`

I am trying to update a clock time in a h1 element. I am trying to update the time by calling a function by setting interval, But i am not able to call. I find a solution to apply .

But i would like to understand the logic behind this. any explain me the reason why i am not able to call and why should we use the apply method..?

here is my work:

 angular.module('Book', []) .controller('MyController', function ($scope) { var updateClock = function() { $scope.clock = new Date(); }; setInterval(function() { updateClock(); //not working when i call from here...? //$scope.$apply(updateClock); //it works! }, 1000); updateClock(); //it works in first time. }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="Book"> <div ng-controller='MyController'> <input ng-model="name" type="text" placeholder="Your name"> <h1>Hello {{ clock }}</h1> </div> </div> 

In short

Angular run $digest cycle on some particular event($digest cycle is actually responsible for the two way data binding or for dirty checking).The event may be when $scope function is called ,$http return data ,$timeout,$interval etc.But if you used other than this then angular does not know that any thing is change( like say setTimeout which is javascript function).So we explicitly need to tell the angular and for this angular gives us $apply.

In long

Refer this link http://tutorials.jenkov.com/angularjs/watch-digest-apply.html

Inside your controller, use $interval instead of setInterval . $interval will trigger the $digest cycle automatically. SO you need not call the $scope.$apply manually. instead it will be implicitly called by $interval . Do remember to inject $interval in your controller as dependency as well.

You must use $scope.$apply only when you outside of angular context. For example you're using jQuery to do some part, then you must let angular to know about the changes via $scope.$apply but when you're inside your controller, it's not required at all.

 angular.module('Book', []) .controller('MyController', function ($scope, $interval) { var updateClock = function() { $scope.clock = new Date(); }; $interval(function() { updateClock(); //not working when i call from here...? //$scope.$apply(updateClock); //it works! }, 1000); updateClock(); //it works in first time. }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="Book"> <div ng-controller='MyController'> <input ng-model="name" type="text" placeholder="Your name"> <h1>Hello {{ clock }}</h1> </div> </div> 

Basically, $scope.apply() is applying the change to the scope in the view, therefore it works when you use the apply.

To update the scope without it you should the Angular's $interval service, instead of setInterval() function. This basically calls the $apply() function within the service and thus changing the view, without the need to call the $apply function to implement the change.

Here is plunker for you

You should use $interval angular service rather than setInterval of javascript.

 $interval(function() {
        updateClock(); //not working when i call from here...?
        //$scope.$apply(updateClock); //it works!
    }, 1000);

Now why you need to $scope.apply() for setInterval is because you are working outside the scope of angular and you need to execute the digest cycle manually to validate it inside angular scope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM