shunryu111
shunryu111

Reputation: 6543

AngularJS view not updating on model change

i'm trying to figure out how Angular works and am having trouble getting my view to update when the model changes..

HTML

<div ng-app="test">  
        <p ng-controller="TestCtrl">  
            {{testValue}}  
        </p>  
    </div>

JS

var app = angular.module('test', []);

    app.controller('TestCtrl', function ($scope) {
       $scope.testValue = 0;

        setInterval(function() {
            console.log($scope.testValue++);
        }, 500);
    });

http://jsfiddle.net/N2G7z/

any ideas?

Upvotes: 78

Views: 109706

Answers (4)

Ana Caroline Ferreira
Ana Caroline Ferreira

Reputation: 81

Do not use $scope.$apply() angular already uses it and it can result in this error

$rootScope:inprog Action Already In Progress

if you use twice, use $timeout or interval

Upvotes: 8

Diego Vieira
Diego Vieira

Reputation: 1149

Just use $interval

Here is your code modified. http://plnkr.co/edit/m7psQ5rwx4w1yAwAFdyr?p=preview

var app = angular.module('test', []);

app.controller('TestCtrl', function ($scope, $interval) {
   $scope.testValue = 0;

    $interval(function() {
        $scope.testValue++;
    }, 500);
});

Upvotes: 37

Boris Ivanov
Boris Ivanov

Reputation: 4254

As Ajay beniwal mentioned above you need to use Apply to start digestion.

var app = angular.module('test', []);

app.controller('TestCtrl', function ($scope) {
   $scope.testValue = 0;

    setInterval(function() {
        console.log($scope.testValue++);
        $scope.$apply() 
    }, 500);
});

Upvotes: 126

Davin Tryon
Davin Tryon

Reputation: 67326

setTimout executes outside of angular. You need to use $timeout service for this to work:

var app = angular.module('test', []);

    app.controller('TestCtrl', function ($scope, $timeout) {
       $scope.testValue = 0;

        $timeout(function() {
            console.log($scope.testValue++);
        }, 500);
    });

The reason is that two-way binding in angular uses dirty checking. This is a good article to read about angular's dirty checking. $scope.$apply() kicks off a $digest cycle. This will apply the binding. $timeout handles the $apply for you so it is the recommended service to use when using timeouts.

Essentially, binding happens during the $digest cycle (if the value is seen to be different).

Upvotes: 30

Related Questions