All:
I got a question about how angularjs data digest monitor the changing of scope data, for example:
<button ng-click="changename()">{{name}}</button>
And the data change function is like:
$scope.name = "Change Name";
$scope.changename = function(){
$scope.name = "name1";
$scope.name = "name2";
}
$scope.$watch("name", function(newname, oldname){
if(newname!=oldname){
console.log("new: "+newname, "old: "+oldname);
}
});
This changename function change scope.name twice in a row, but the watcher can only catch the change from "Change Name" to "name2" ( the console only print "new: name2 old: Change Name")
Could anyone confirm my guess that the digest cycle only start after a function block finish executing?
Thanks
I want to correct the answer from rbaghbanli
which is misleading.
Indeed, because JavaScript is single threaded, what happen when you click on that button is:
The variable `$scope.name` is set to "name1";
The variable `$scope.name` is set to "name2";
> end of execution stack
Angular runs a $digest cycle
The $watchers are executed
since a watcher value has changed, angular runs another $digest cycle
The $watchers are executed
The watcher have the same value, end of $digest cycle
> end of execution stack
So basically no watcher nor anything will happen when you are within the same function, until the end of every line of this function.
The reason why Angular runs a digest cycle after your changename
call is because it is within a ng-click
directive, and as with all Angular built-in directive, the code is actually wrapped inside a $scope.$apply
call. You could read the ng-click
as the following code (even if technically it is not exactly like this):
element.on('click', function() {
$scope.changename();
$rootScope.$digest();
});
Note: I wanted to simplify the generic idea, but to be technically true, Angular executes its $digest cycle right after your code (as you can see in my pseudo ng-click
), within the same execution stack. Which means any setTimeout
or other asynchronous call will happen after the digest cycle and after the DOM has been updated with the latest changes, which can be useful sometimes.