Reputation: 15309
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>
Upvotes: 1
Views: 1296
Reputation: 473
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
Upvotes: 2
Reputation: 18576
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>
Upvotes: 1
Reputation: 14037
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.
Upvotes: 0
Reputation: 2100
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.
Upvotes: 0