How does AngularJS know when variables change? How does AngularJS dirty checking work?

JavascriptAngularjsObserver Pattern

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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:

Solution 2 - Javascript

Angular Dirty Checking mechanism workflow.

enter image description here

> 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

Solution 3 - Javascript

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.

Solution 4 - Javascript

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

Solution 5 - Javascript

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.

Solution 6 - Javascript

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmfrachetView Question on Stackoverflow
Solution 1 - JavascriptlanteView Answer on Stackoverflow
Solution 2 - JavascriptfluffyBatmanView Answer on Stackoverflow
Solution 3 - JavascriptSanjay DwivediView Answer on Stackoverflow
Solution 4 - JavascriptDeepanjan GhoshView Answer on Stackoverflow
Solution 5 - JavascriptAbhishekIIITView Answer on Stackoverflow
Solution 6 - JavascriptTwinView Answer on Stackoverflow