How does AngularJS know when variables change? How

2020-02-16 06:28发布

问题:

I was reading some article to understand a little bit more how AngularJS works.

One of the terms that I didn't understand is Dirty Checking.

What is it exactly? It seems like the Observer pattern but apparently it's better.

Can you help me understand this please?

EDIT : it can be also useful for people who wants to learn more about that to watch this video from swiip at NgEurope some years ago.

回答1:

From this link:

Angular defines a concept of a so called digest cycle. This cycle can be considered as a loop, during which Angular checks if there are any changes to all the variables watched by all the $scopes. So if you have $scope.myVar defined in your controller and this variable was marked for being watched, then you are explicitly telling Angular to monitor the changes on myVar in each iteration of the loop.

This "digest" is also called "dirty checking", because, in a way, it scans the scope for changes. I cannot say if it's for better or for worse than observable pattern. It depends on your needs.

Some links:

  • Angular documentation
  • A blog post about Angular scopes


回答2:

Angular Dirty Checking mechanism workflow.

Dirty checking is a simple process that boils down to a very basic concept: It checks whether a value has changed that hasn’t yet been synchronized across the app.

Our Angular app keeps track of the values of the current watches. Angular walks down the $watch list, and, if the updated value has not changed from the old value, it continues down the list. If the value has changed, the app records the new value and continues down the $watch list.

Check out the whole article here



回答3:

What is dirty checking?

The process of checking every watch to detect the changes, is called dirty checking. There could be two scenarios

First –

  1. Get a watch from list
  2. Check whether item has been changed
  3. If there is no change in item then
  4. No Action taken, move to next item in watch list

Second–

  1. Get a watch from list
  2. Check whether item has been changed
  3. If there is Change in an item
  4. DOM needs to be updated, return to digest loop

In second case, loop continues till it finds no changes in the entire loop. And once it completes, DOM gets updated if required.



回答4:

Just modifying a previous answer...

Angular has a concept of ‘digest cycle’. You can consider it as a loop. In which Angular checks if there are any changes to all the variables watched by all the $scopes(internally $watch() and $apply() functions are getting bonded with each variable defined under $scope).

So if you have $scope.myVar defined in your controller (that means this variable ‘myVar’ was marked for being watched) then you are explicitly telling Angular to monitor the changes on ‘myVar’ in each iteration of the loop. So when the value of ‘myVar’ changes, every time $watch() notices and execute $apply() to apply the changes in DOM.

This "Digest" is also called "dirty checking", because, in a way, it scans the scope for changes. As all watched variable are in a single loop(digest cycle), any value change of any variable forces to reassign values of other watched variables in DOM.

PROS : This is the way Angular achieves Two-way data binding.

CONS : If there are more watched variables in a single page (>2000–3000), you may see lag while page loading.(But I say if there are that many ‘watched variables’ in a single page, it is a bad page design :p).

There are other cons, as well as are workarounds also :D



回答5:

I read a great article about dirty checking in this blog post. There was also this SO answer

TLDR; version

When the $digest cycle kicks in, the watchers will check for any changes in the scope model and if there are any (the change might also come from out-of-Angular-domain), the corresponding listener functions are executed. This will again run the $digest loop and checks if the scope model was changed (the listener function could also modify the scope model).

Overall, the $digest cycle will run twice even if the listener does not change the model or till it hits the max loop count of 10.



回答6:

Dirty checking will check anything changes in $scope variable and update it to the DOM. This done by angular js, you can also implement dirty checking by your own.