All this has to do with the Angular processing cycle. I will try to demonstrate this with an example before I tell you what a digest cycle is. Provide the following code:
angular.module('app', []).controller('TestController', ['$scope', function($scope){ $scope.name = 'Tom'; setTimeout(function(){ $scope.name = 'Bob'; }, 2000); }]);
There is an inherent problem in this code. Once we change the $scope.name
variable after 2 seconds, Angular is completely unaware of this change to $scope.name
. If you now consider the following example, which uses $timeout
instead of $timeout
:
angular.module('app', []).controller('TestController', ['$scope', '$timeout', function($scope, $timeout){ $scope.name = 'Tom'; $timeout(function(){ $scope.name = 'Bob'; }, 2000); }]);
Angular will call an anonymous function after two seconds, however then the Angular digest loop will start. This is the main difference between $timeout
and setTimeout
, a digest cycle loop.
The (simple) Angular digest loop iterates over all observers (bindings), checks for any changes, and re-renders when they fit. You may have seen the mention of $scope.$apply
elsewhere - here's how to start a digest cycle.
As for the example you pointed out: if $timeout
not used, Angular will not know that any changes have been made, and as such, your view will not be updated. I mentioned $scope.$apply
before, so you might be wondering why we are not just using this instead? The problem with using $scope.$apply
is that you cannot be sure that the digest loop is no longer running. If you call it while recording, you will see the error message " $digest is already in progress
". $timeout
will only work after the current loop and, as such, this error will not be executed.
People often use $timeout
without any delay to notify Angular that the change was made by a third party (such as a file loader) that she otherwise did not know what happened.
Hope this clarifies the situation.
Tom