--@angularjs--Understanding $apply () and $digest () in angular

Source: Internet
Author: User

$apply () and $digest () are two core concepts in AngularJS, but sometimes they are confusing. To understand how AngularJS works, you first need to understand how $apply () and $digest () work. This article is intended to explain what $apply () and $digest () are, and how they are applied in everyday coding.

Explore $apply () and $digest ()

AngularJSProvides a very cool feature called two-way data binding(Two-way Data Binding), this feature greatly simplifies the way our code is written. Data binding means that when theview scope scope scope model changes, view The data in is also updated to the most recent value. So angularjs {{AModel}} watcher " scope It is used to update view watcher angularjs "en-US" watcher

 $scope.  $watch ( ' AModel ', function (NewValue, oldValue) {//update the dom with newvalue}";      

incoming to $watch () The second parameter is a callback function, which is amodel view angularjs How do you know when to invoke this callback function? In other words, angularjs amodel scope Does the data in the model change? Well, this is where loop.

In the $digest Loop, the watchers is triggered. When a watcher is triggered, AngularJS detects the scope model and how it changes so that the callback function associated to the watcher is called. So the next question is, when does the $digest cycle start in various ways?

After calling the$scope. $digest ()After$digestThe cycle begins. Suppose you're in aNg-clickdirective corresponds to theHandlerfunction changes theScopeOne of the data in thisAngularJSis automatically passed through the call to the$digest ()To trigger a round$digestCycle. When$digestOnce the loop is started, it triggers eachWatcherwatchers scope model model view ({{AModel}) ng-click directives, there are other built-in Instructions and services to let you change models ( e.g. ng-model $timeout et ) $ Digest loop.

so far so good! However, there is a small problem. In the above example, angularjs $digest () $scope. $apply () $rootScope. $digest () $digest cycle in $rootScope start, It will then be accessed to all children scope watchers

Now, let's say that you will ng-click button Span lang= "ZH-CN" > and passed in a function ng-click button is clicked, angularjs will this function packaged into a wrapping function $scope. $apply () function models ( $digest loops will also be triggered to ensure that the Span lang= "en-US" >view

Note: $scope. $apply () automatically calls $rootScope. $digest () . There are two forms of the $apply () method. The first one takes a function as a parameter, executes the function and triggers a round $digest Loop. The second one will not accept any arguments, just trigger a round of $digest loops. We'll see now why the first form is better.

When do I manually invoke the $apply () method?

IfAngularJSAlways put our codeWrapto afunctionIn and incoming$apply ()To start a round$digestLoop, then when do we need to manually call$apply ()Method? As a matter of factAngularJSThere is a very clear requirement that it is only responsible for theAngularJSChanges in the context are automatically responded to(That is, in$apply () change in method of models angularjs built-in directive that's what this is, so any of the The change of span lang= "en-US" >model view model " angularjs angularjs $apply () angularjs models angularjs watchers

For example, if you use setTimeout () in JavaScript to update a scope model , there is no way for AngularJS to know what you have changed. In this case, calling $apply () is your responsibility, by invoking it to trigger a round of $digest loops. Similarly, if you have an instruction to set up a DOM event listener and modify some models in the listener , you also need to manually invoke the c21> $apply () to ensure that changes are correctly reflected in the view .

Let's take a look at an example. Join you have a page, once the page has been loaded, you want to display a message after two seconds. Your implementation might look something like this:

Html:

<ng-app="myApp" >  <ng-controller=</</body>  

Javascript:

/* What happens without an  $apply () */ Angular.module ( $scope) { $scope. GetMessage = function () {setTimeout (function () { span class= "variable" > $scope. Message =  ' fetched after 3 seconds '; Console. $scope. message);}, 2000);}  $scope. GetMessage (); });

by running this example, you will see that after two seconds, the console does show the updated model view $apply () getmessage ()

/* What happens with  $apply */ Angular.module ( $scope) { $scope. GetMessage = function () {setTimeout (function () { span class= "variable" > $scope.  $apply (function () {//wrapped this within  $apply  $scope. Message =  ' fetched after 3 seconds '; Console. $scope. message);}); }, 2000); }  $scope. GetMessage ();});           

If you run the example above, you will see that the view is updated after two seconds. The only change is that our code is now wrapped to $scope. $apply () , it automatically triggers $rootScope. $digest () , allowing watchers is triggered to update the view .

Note: By the way, you should use the $timeout service instead of SetTimeout () , because the former will help you call $apply () , So you don't need to call it manually.

Also, note that in the above code you can manually invoke the $apply () without parameters after modifying the model , as follows:

$scope. getMessage = function () {  setTimeout (function () {    ' fetched after seconds ';    Console.log ($scope. message);    $scope. ; };   

The code above uses the second form of the $apply () , which is the form without parameters. Remember that you should always use a $apply () method that accepts a function as a parameter . This is because when you pass a function into the $apply ( ), the function is wrapped in a try ... catch block, so that if an exception occurs, the exception is handled $exceptionHandler service .

How many times will the $digest loop run?

when a $digest loop run, watchers scope models Whether there has been a change. If there is a change, then the corresponding listener listener scope model angularjs What will you do with this situation?

The answer is $digest The loop will not run only once. At the end of the current cycle, it will perform a loop again to check if there is a models (Dirty Checking) listener The function is executed when the model $digest model $digest The number of cycles reached 10 times. Therefore, do not modify lang= zh-cn "en-US" model " listener

Note: The $digest Loop will run at least two times, even if the listener function does not change any model . As discussed above, it will run more than once to ensure that the models is unchanged.

Conclusion

I hope this article explains the $apply and $digest clearly . The most important thing to remember is whether AngularJS can detect your modifications to the model. If it cannot be detected, then you need to call $apply () manually .

[email protected] understand $apply () and $digest () in angular

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.