$watch(), $digest() and $apply() in AngularJS $scope are the core functions of AngularJS. You must understand these functions to learn AngularJS.
When binding variables in $scope to view, AngularJS automatically creates a "Watch" internally. "Watch" is used to monitor changes in variables in the AngularJS scope. A "Watch" can be created by calling the $scope.$watch() method.
The $scope.$digest() function will loop through all watches and detect whether the variables in the $scope it is listening to have changed. If the variable changes, the listening function corresponding to the variable will be called. The listening function can perform many operations, such as letting the text in HTML display the latest variable value. It can be seen that $scope.$digest can trigger data binding updates.
In most cases, AngualrJS will automatically call the $scope.$watch() and $scope.$digest() functions, but in some cases, we need to call them manually, so it is necessary to understand how they work working.
$scope.$apply() This function will first execute some code and then call $scope.$digest(). All watches will be tested once and the corresponding listening functions will be executed. $scope.$apply() is useful when integrating AngularJS with other JavaScript code.
Next we will explain $watch(), $digest() and $apply() in detail.
$watch()
$watch(watchExpression, listener, [objectEquality])
watchExpression: monitoring object, which can be string or function(scope){}
listener: callback function function(newVal, oldVal, scope){}
executed when the listening object changesobjectEquality: Whether to monitor deeply. If set to true, it tells Angular to check every property change in the monitored object. You should use this if you wish to monitor individual elements of an array or a property of an object rather than a plain value. (Default: false)
$digest()
Detect all watches in the current scope and sub-scopes, because the listening function will modify the model (variables in the scope) during execution, and $digest() will continue to be called until the model does not change anymore. When called more than 10 times, $digest() will throw an exception "Maximum iteration limit exceeded' to prevent the program from entering an infinite loop.
$apply()
$apply([exp])
exp: string or function(scope){}
The $apply() life cycle pseudocode diagram is as follows
function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } }
Example
Below we use an example to illustrate $watch, $digest and $apply.
<script> var module = angular.module("myapp", []); var myController1 = module.controller("myController", function($scope) { $scope.data = { time : new Date() }; $scope.updateTime = function() { $scope.data.time = new Date(); } document.getElementById("updateTimeButton") .addEventListener('click', function() { console.log("update time clicked"); $scope.data.time = new Date(); }); }); </script> <body ng-app="myapp"> <div ng-controller="myController"> {{data.time}} <br/> <button ng-click="updateTime()">update time - ng-click</button> <button id="updateTimeButton" >update time</button> </div> </body>
This code will bind $scope.data.time to HTML for display. At the same time, this binding will automatically create a watch to monitor changes in $scope.date.time. In addition, there are 2 buttons here. The first button calls the $scope.updateTime method through ng-click Directive. Afterwards, AngularJS will automatically execute $scope.$digest() to display the latest time in HTML. The second button adds a click event through javascript code to update the time in the HTML. But the second button does not work. The solution is to manually call the $scope.$digest() method at the end of the click event, as follows:
document.getElementById("updateTimeButton") .addEventListener('click', function() { console.log("update time clicked"); $scope.data.time = new Date(); $scope.$digest(); });
Another solution is to call $scope.$apply(), as follows:
document.getElementById("updateTimeButton") .addEventListener('click', function() { $scope.$apply(function(){ console.log("update time clicked"); $scope.data.time = new Date(); } ); });
The above is the entire content of this article, I hope it will be helpful to everyone’s study.