I'm trying to create a "Clock" directive as a way to learn Angular. How would I go about making sure it "ticks?"
Here's what I tried fiddle Link:
angular.module('app')
.directive('clock' , function(){
return {
restrict: 'E',
template: '<div>{{date}}</div>',
link: function(scope, elem, attr){
scope.date = getDate();
setInterval(function(){
scope.date = getDate();
}, 100);
}
}
})
Using setInterval to upate the scope variable isn't working. I'm assuming because the directive isn't watching for it to be changes anymore?
It is updating the scope variable, but Angular isn't aware of the change.
It is recommended to use Angular $interval
.
Here is your fiddle with $interval
: https://jsfiddle.net/oafcde6g/11/
In other words, Angular doesn't do any magic by "listening" to scope properties, it simply does dirty-checking. But to do it, it needs to be notified that something changed. So if you really wanted to use setInterval
instead of $interval
, you could notify it manually that something changed:
setInterval(function () {
scope.$apply(function () {
scope.date = getDate();
});
});
This way, you're notifying it to run your anonymous function inside $apply
and then digest the scope, checking if anything changed. If it did, it will update the view.
Even though it looks like angular automatically knows to rerender the view when you click/change something by using it's built-in directives, it really isn't so.
Some simple implementation of ng-click
would look something like:
angular.module('app')
.directive('ngClick' , function(){
return {
restrict: 'A',
link: function(scope, elem, attr){
elem.on('click', function () {
scope.$apply(function () {
scope.$eval(attr.ngClick);
});
});
}
}
})
You can see this for yourself if you try to bind click event normally, outside of angular context and make it change a scope variable. It won't update until you explicitly tell it to (like we did in setInterval
example).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With