1

I'm new to angular.js. I'm confused with how to handle asynchronous events in the controller.

For example, in a page, I have a view named count. And while I click on a button, the controller increase the count by 1. But the increase is asynchronous. What I want is, when count changed, the view will be notified and change its value. But util the next click, the view will not change its value.

This is the code for example:

<!DOCTYPE html>
<html ng-app>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
  </head>

  <body>
    <div ng-controller="Controller">
      {{ count }}
      <form ng-submit="delayInc()">
        <input type="submit" value="Add" />
      </form>
    </div>

    <script>
      function Controller($scope) {
        $scope.count = 0;

        $scope.delayInc = function () {
          setTimeout(function () {
            $scope.count += 1;
          }, 1000);
        };
      }
    </script>
  </body>
</html>

Update:

Thanks for all your answers. But I'm asking a generate question. How about the setTimeout function is a http request? I know there is $http could do this. But what if the function is something handle a file and so on? I don't except every async call have a service for me. Do I need to write my own one if it dose not exist?

1
  • but when you do form submit then whole page is reloading and you will never see the variable's changes Commented Jun 18, 2013 at 10:48

2 Answers 2

4

Use the $timeout service instead of the native setTimeout:

function Controller($scope, $timeout) {
    //                      ^---- Don't forget to inject the service
    $scope.count = 0;

    $scope.delayInc = function () {
        $timeout(function () {
            $scope.count += 1;
        }, 1000);
    };
}

Alternatively, you can tell Angular to apply your changes manually using Scope.$digest() (the $timeout service shown above will effectively do this for you):

function Controller($scope) {
    $scope.count = 0;

    $scope.delayInc = function () {
        setTimeout(function () {
            $scope.count += 1;
            $scope.$digest();
        }, 1000);
    };
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I have updated my question. Could you have a look please?
@BinWang - The 2nd example in my answer can apply to the general case. But I would suggest using the Angular services where possible. If you want to write your own, you'll want to use promises - look at the $q service.
0

Due to the nature of the AngularJS $scope you need to replace the setTimeout call with the $timeout service.

Comments

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.