How does AngularJS update the DOM?

In particular, I am wondering how they update elements without using innerHTML. In the documents, they clearly state that they are better than other templates, because they do not redraw with innerHTML (ctrlf innerHTML - sorry). I started sneaking through the source code, but there were many, and I was hoping that maybe I could get a quicker answer from you.

So far my guesses have been

  • The compiler converts {{test}} to something like <ng-bind>test</ng-bind> , which the linker can update when the data changes, but it doesn't seem to happen when I look at the DOM on the Angular page. It also seems that this could interfere with the CSS client and other javascript components external to Angular.
  • They actually use innerHTML, but they just don't redraw the ENTIRE DOM - it's just a small piece of code (perhaps the data inside some kind of custom <ng-bind></ng-bind> ).
  • They somehow remove and add new elements ... I think, I think.

If someone knows that I would like to study. Otherwise, it will return to the source code for me.


EDIT New guess

After thinking about this a little more, I believe that this can happen: the compiler swallows html, it will say something like

 <p> {{model}} <div> <p> Hello ! </p> </div> </p> 

And converts it to this:

 <p class="ng-binding"> {{model}} <div> <p> Hello ! </p> </div> </p> 

Angular can then scan and index all Angular text nodes ( {{model}} ) eg document.getElementsByClass('ng-binding')[0].childNodes[0] . Each saved node can then be linked by the linker to the model with the scope $scope['model'] . Each node can be quickly updated by setting node.nodeValue = $scope['somemodel ] (simplified) `and voilà, technically without innerHTML' and DOM updates at lightning speed.

+4
source share
1 answer

Instead of replacing the element itself, as innerHTML did, Angular prefers to modify the properties of existing elements.

The ng-bind directive is actually a good example. It saves the element reference and simply updates its .text() as changes to $scope ( source ):

 var ngBindDirective = ngDirective(function(scope, element, attr) { element.addClass('ng-binding').data('$binding', attr.ngBind); scope.$watch(attr.ngBind, function ngBindWatchAction(value) { element.text(value == undefined ? '' : value); }); }); 

This does not necessarily mean that Angular will not use innerHTML from time to time, especially when creating new content. But he tries to avoid it when possible.

+4
source

Source: https://habr.com/ru/post/1496690/


All Articles