Reproduced AngularJS and scope. $apply

Source: Internet
Author: User

Http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Http://www.cnblogs.com/zhrj000/p/3383898.html

If you've written a non-trivial amount of code in AngularJS, your may has come across the $scope.$apply() method. On the surface, it could seem like just a method of call to get your bindings to update. But why does it exist? And when does your need to use it?

To really understand - $apply to-use, it's good to know exactly Why we need to use it, so let's dive I N!

JavaScript is Turn Based

The JavaScript code we write doesn ' t all run on one go, instead it executes in turns. Each of the These turns runs uninterupted from start to finish, and when a turn are running, nothing else happens in our browse R. No Other JavaScript code runs, and we Web page interface is completely frozen. This is why poorly coded JavaScript can freeze a Web page.

Instead, whenever there is a task this takes some amount of time, such as an Ajax request, waiting for a click event, or S Etting a timeout, we set up a callback function and finish our current turn. Later, when the Ajax request completes, a click was detected, or the timer completes, a new JavaScript turn is created and The callback is run to completion.

Let's look at an example JavaScript file:

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

When the JavaScript code was loaded, that's a single turn. It finds a button, adds a click Listener, and sets a timeout. Then the turn are complete, and the browser would update the Web page if necessary, and begin accepting user input.

If The browser detects a click on #clickMe , it creates a new turn, which executes the buttonClicked function. When this function returns, that turn are complete.

After milliseconds, the browser creates a new turn which calls timerComplete .

Our JavaScript code was run in turns, and in between the turns are when the page was repainted, and input is accepted.

How do we update bindings?

So Angular lets us bind parts of We interface to data in our JavaScript code, but what does it know when data changes, and The page needs updating?

There is a few solutions. The code needs to know when a value has changed. Right now there is the no-right-of-our-code to being directly notified of changes on an object 1. Instead there is the main strategies.

One strategy is to use special objects, where the data is set via methods and not the property assignments. Then changes can and is noted, and the page can be updated. This have the downside in that we must extend some special object. Also, for assigning, we must use a more verbose form obj.set(‘key‘, ‘value‘) instead of obj.key = ‘value‘ . Frameworks like Emberjs and Knockoutjs use this strategy.

AngularJS takes a different approach:allow any value to be used as a binding target. Then at the end of any JavaScript code turn, check the If the value has changed. This could seem inneficient at first, but there is some clever strategies to reduce the performance hit. The big benefit is we can use normal objects and update our data however we want, and the changes would be noticed and REFL Ected in our bindings.

For the strategy to work, we need to know when the data has possibly changed, and the is where $scope.$apply comes into play.

$apply and $digest

That step is checks to the see if any binding values having changed actually has a method, $scope.$digest() . That's actually where the magic happens, but we almost never call it directly, instead we use $scope.$apply() which $scope.$digest() would call For you.

$scope.$apply()Takes a function or an Angular expression string, and executes it, then calls to $scope.$digest() update any bindings or watchers.

So, when does need to call $apply() ? Very rarely, actually. AngularJS actually calls almost all of your code within a $apply call. Events like ng-click , controller initialization, $http callbacks is all wrapped in $scope.$apply() . So your don ' t need to call it yourself, in fact you can ' t. Calling $apply inside $apply would throw an error.

You do need to use it if you are going to run code in a new turn. And only if that turn isn ' t being created from a method in the AngularJS library. Inside that new turn, you should wrap your code in $scope.$apply() . Here's an example. We are using setTimeout , which would execute a function in a new turn after a delay. Since Angular doesn ' t know about that new turn, the update is not being reflected.

But, if we wrap the code for that turn in $scope.$apply() , the change would be noticed, and the page is updated.

As a convenience, AngularJS provides $timeout, which is like setTimeout , but automatically wraps your code in $apply by default . Use.

If you write any code this uses Ajax without $http , or listens for events without using Angular ' s ng-* listeners, or sets A timeout without $timeout , you should wrap your code in$scope.$apply

$scope. $apply () vs $scope. $apply (FN)

Sometimes I see examples where data are updated, and then are $scope.$apply() called with no arguments. This achieves the desired result, but misses some opportunities.

If your code isn ' t wrapped in a function passed to $apply, and it throws an error, that's error is thrown outside of Angular JS, which means any error handling being used in your application are going to miss it. $apply not only runs your code, but it runs it in a so try/catch your error was always caught, and the $digest call was in a clause, meaning it'll run regardless of an error being thrown. That ' s pretty nice.

Hopefully now-understand what's and when to use $apply it. If you have only the use of what AngularJS provides, you shouldn ' t need to use it often. But if you begin writing directives where you are observing DOM elements directly, it's going to become necessary.

Object.observe have been proposed for ES5, but was only experimentally implemented now

Reproduced AngularJS and scope. $apply

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.