0

I have a question about using ng-class to change DOM class. Most of the buttons work fine, except "Two Blink" button. I have already called $scope.$digest, but the I can't see the effect on setTimeout 500ms. Why?

Any help is appreciated!

HTML Code

<html>
    <title>
        Angular Blink Test
    </title>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script src="app.js"></script>

    <body ng-app='app'>
        <style>
            .bk_red  {background-color:red;}
            .bk_blue {background-color:blue;}
        </style>

        <div ng-class='{bk_red: isRed, bk_blue:!isRed}' ng-controller='myController'>
            <button ng-click='buttonClick0()'>Check</button>
            <button ng-click='buttonClick1()'>One Blink</button>
            <button ng-click='buttonClick2()'>Two Blink</button>
            <button ng-click='buttonClick3()'>HTTP</button>
        </div>
    </body>
</html>

JavaScript Code

(function () {
    'use strict';
    // this function is strict...

    var app = angular.module('app', []).controller('myController', function ($scope, $http) {
        $scope.isRed = false;

        $scope.buttonClick0 = function () {
            alert('isRed=' + $scope.isRed);
        };

        $scope.buttonClick1 = function () {
            $scope.isRed = !$scope.isRed;
            console.log('buttonClick1 isRed:', $scope.isRed);
        };

        $scope.buttonClick2 = function () {
            $scope.isRed = !$scope.isRed;
            console.log('buttonClick2 isRed-1:', $scope.isRed);
            setTimeout(function () {
                $scope.isRed = !$scope.isRed;   //change again, but NOT working!
                $scope.$digest;  //I guess something else should be done here.
                console.log('buttonClick2 isRed-2:', $scope.isRed);
            }, 500);
        };

        $scope.buttonClick3 = function () {
            $scope.isRed = !$scope.isRed;
            console.log('buttonClick3 isRed-1:', $scope.isRed);
            $http(
                {
                    method: 'GET',
                    url: '/data.js'
                }).
                then(function successCallback(response) {
                    $scope.isRed = !$scope.isRed;
                    console.log('buttonClick3 isRed-2:', $scope.isRed);
                }, function errorCallback(response) {
                    $scope.isRed = !$scope.isRed;
                    console.log('buttonClick3 isRed-3:', $scope.isRed);
                });
        }
    });
}());

http://plnkr.co/edit/z1DGyAvZMKP3zgoqSawH?p=preview

5
  • Use $interval or $timeout instead. And be sure to call cancel() when your scope is destroyed. Commented Mar 31, 2016 at 22:04
  • Yes, $timeout will work. But I am using setTimeout to simulate some other thread job. Commented Mar 31, 2016 at 22:06
  • Is there a way not to use $interval or $timeout? I want to enforce Angular.JS to check dirty again for everything. Commented Mar 31, 2016 at 22:07
  • It calls setTimeout under the hood, but it handles all the digest stuff for you. If you're going to insist on setTimeout, you should still cancel it because you will get a memory leak. Commented Mar 31, 2016 at 22:08
  • 1
    Using $interval or $timeout will force angular to check dirty again. That's what they are for. Commented Mar 31, 2016 at 22:09

1 Answer 1

1

You need to call $scope.$digest() rather than $digest if you want to kick off a digest cycle.

The proper thing to do, though, is to use $timeout instead of setTimeout. That will properly apply changes inside the angular digest cycle.

https://docs.angularjs.org/api/ng/service/$timeout

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your help! It works on the test code. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.