tamir
tamir

Reputation: 3297

$interval refreshing directives

Please take a look at this code: (on plunker)

angular
    .module('intervalExample', [])
    .controller('ExampleController', ['$scope', '$interval', function($scope, $interval) {
            $interval(function() {
                //nothing..
            }, 1000);

            $scope.do = function() {
                console.log(new Date());
                return true;
            }
    }]);

<body ng-app="intervalExample">
    <div>
        <div ng-controller="ExampleController">
            <div ng-if="do()">text</div>
        </div>
    </div>
</body>

If you open the console you'll see that $scope.do is being called every second. Why is that? why is $interval causing the directive to reload? Is there a way to avoid it?
It happens with other directives (such as ngShow) as well..

Upvotes: 1

Views: 1550

Answers (2)

Ergo
Ergo

Reputation: 1234

Yes, I think this is because $interval causes digest pass and ng-if gets tested every time this happens, so your $scope.do() gets evaluated every time.

I don't think passing in a callable there is a good idea in general.

Upvotes: 1

Dark Falcon
Dark Falcon

Reputation: 44181

This is the entire point of how Angular works. Every time the handler registered via $interval fires, Angular does a digest cycle, which means it checks every watch expression to see if anything has changed. If a change is detected, Angular will modify the DOM to reflect the change. Because do() is called by a watch expression registered by ng-if, it is also called every time the timer fires.

If you don't want this, don't use $interval; just use a normal setInterval call, but note that any data you modify within the callback will not cause your Angular templates to be updated. This approach is not recommended. Rather, if the problem with calling do() every second is that do() is too expensive, find a way to make it cheaper, such as by caching the result.

Upvotes: 3

Related Questions