preface

$scope.$apply() {$scope.$apply() {$scope.

JavaScript execution order

JavaScript is single-threaded, and the code runs in the order of the code snippets, with each block never being interrupted from execution to completion, which is why the browser blocks, with one part running, causing all the other blocks to freeze.

Whenever a time-consuming task occurs, such as waiting for a click event or a response to an Ajax request, we set up a callback function. When the click event is triggered or the timer completes, a new JavaScript turn is created and executed. If you don’t know how JS works, you can go to the js runtime article for more help.

var button = document.getElementById('clickMe');
 
function buttonClicked () { 
 
 alert('the button was clicked'); 
 
 }
 
button.addEventListener('click', buttonClicked); 
 
  
 
function timerComplete () { 
 
 alert('timer complete'); 
 
}
 
setTimeout(timerComplete, 2000);
Copy the code

When the JavaScript code starts running, find a Botton and add a click listening event with a timeout. The browser updates the Web after this code is executed and accepts user input.

If the browser detects that a new clicked event has occurred, it will start a turn, which executes the buttonClicked function. When the function completes, the phase ends.

After 2000 milliseconds, the browser creates a procedure to execute timerComplete. In between, the page is redrawn and input is received.

How to update binding data

Angular provides interfaces to bind JavaScript code to data. It is actually the $Digest function that checks for changes in the data, but instead of using the $Digest function directly, you usually use $apply, which calls $Digest to update the monitor after receiving an expression or function as an argument.

In fact, Angular adds $apply to almost everything it provides, such as ng-click, the initial controller, and the $HTTP callback. You don’t need to call $apply yourself, and repeated calls will cause errors.

Therefore, use $apply only when you run [a new phase] that is not part of an Angular library. There is code for setTimeout. After a delay of 2000 milliseconds, the code executes [a new phase], but Angular does not know that the data has been updated, so the update is not displayed.

$scope.message = "Wait 2 seconds to update "; SetTimeout (function () {$scope.message = "time up "; // AngularJS unaware of update to $scope }, 2000);Copy the code

$scope.$apply() : $scope.$apply() : $scope.

$scope.message = "Wait 2 seconds to update "; SetTimeout (function() {$scope.$apply(function() {$scope. })}, 2000);Copy the code

Angular uses $timeout instead of setTimeout to make it easier for you to use. It calls $apply by default.

If you use Ajax calls other than $HTTP in your code, listeners other than ng-*, or timers other than $timeout, should use $scope.$apply to display bindings synchronously.