basis
basis

Reputation: 158

angularjs strange data bindings behavior if you use setTimeout

Look at my fiddle. http://jsfiddle.net/tyF7q/

There is something i dont Understand with the data-bindings in angular.js:

If You click on "addSomething" multiple times, "test3" appears on every click.
Now if you clicking "addSomething2", nothing shows up, even until the 2009ms.
But if you click "addSomething" "test4" will also show up, but only if you click after the 2009ms, otherwise "test4" will also dont appear.
Also if you click "addSomething2" and after 2009ms you click "addSomething2" one "test4" appears.

This is just a simple example of the problem thats appeared as i used socket.io and have some socket.on() event bindings. In That case my "addSomething2" ng-click binding will be socket.on('addSomething2') but the result is still the same.

Because i'm new at angularjs, i dont see what i do wrong here.

html:

 <div ng-app>   
     <div id="edit" ng-controller="Edit">
        <a href="" ng-click="addSomething()">addSomething  </a><br>
        <a href="" ng-click="addSomething2()">  addSomething2</a>
        <div ng-repeat="doneMsgs in doneSoFar">
            {{doneMsgs.status}}:{{doneMsgs.info}} <br>
        </div>
     </div>

    </div>

js:

function Edit($scope) {

$scope.doneSoFar = [];
$scope.doneSoFar.push({status:"test",info:"test"})
var doneSoFarPush = function(status,info){
    $scope.doneSoFar.push({status: status,info:info });
};
doneSoFarPush('test2','test2');

$scope.addSomething = function() {
    doneSoFarPush('test3','test3');
};

$scope.addSomething2 = function() {
    setTimeout(function(){
    doneSoFarPush('test4','test4');
    },2009);
};
};

Upvotes: 0

Views: 761

Answers (1)

Davin Tryon
Davin Tryon

Reputation: 67296

You need to use the $timeout service instead of setTimeout directly. This will allow angular to manage the $digest cycle. Otherwise, you would have to manage the $apply to the scope yourself.

Here is an updated fiddle.

And the updated code:

function Edit($scope, $timeout) {


    $scope.doneSoFar = [];
    $scope.doneSoFar.push({status:"test",info:"test"})
    var doneSoFarPush = function(status,info){
        $scope.doneSoFar.push({status: status,info:info });
    };
    doneSoFarPush('test2','test2');

    $scope.addSomething = function() {
        doneSoFarPush('test3','test3');
    };

    $scope.addSomething2 = function() {
        $timeout(function(){
        doneSoFarPush('test4','test4');
        },2009);
    };
};

Upvotes: 4

Related Questions