3

I have a controller without $scope

angular.module('todoApp', [])
    .controller('TodoListController', function() {
        var todoList = this;

        todoList.title = "Default title";

        setTimeout(function() {
            todoList.title = "Another title will appear after 5 seconds";
        }, 5000);

        // ...some magic here
    });

And view:

<h1>Current title: {{TodoListController.title}}</h1>

This code won't works correctly, becaufe function in setTimeout won't run $digest() which can update my TodoListController.title.

I know I can use $scope and use $scope.$digest(). But - is it possible to run $digest() without it? I have always access to object angular. Maybe through this object?

Kamil P
  • 782
  • 1
  • 12
  • 29
  • not specifically an answer, since the other answers are correct, but just because you use ControllerAs does not mean you are "without `$scope`"... ControllerAs *abstracts* `$scope` by making the controller an aliased object on `$scope`, reducing (but not completely eliminating) your possible needs to interact with `$scope` directly. You should not look at injecting `$scope` *when appropriate* as a bad design. – Claies Oct 26 '16 at 18:07
  • The question results from '$scope is bad' belief, which is false. $scope persecution is the most ridiculous thing that could happen with Angular community. Btw, $scope.$apply can be replaced with $rootScope.$apply and $rootScope.$digest. And btw, there are good reasons why this shouldn't be done and there's no good reason why this should. – Estus Flask Oct 26 '16 at 18:25

2 Answers2

2

You should use $timeout instead of vanilla setTimeout.

angular.module('todoApp', [])
.controller('TodoListController', function($timeout) {
    var todoList = this;

    todoList.title = "Default title";

    $timeout(function() {
        todoList.title = "Another title will appear after 5 seconds";
    }, 5000);

    // ...some magic here
});

Using $timeout from angular will handle starting digest cycle.

Angulars $timeout is also useful if you want to notify angular to do updates without delay. In this case you can invoke it without second parameter.

$timeout(function(){
    //something outside angular ...
});

Function passed to $timeout will be invoked on next digest cycle. This way is better than calling $digest manually because it will prevent digest already in progress errors.

Community
  • 1
  • 1
Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
0

You must use the angular version of timeout: $timeout.

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

This service trigger the angular $digest process.

Danilo Velasquez
  • 451
  • 2
  • 11