Reputation: 823
Specifically, I'm wondering how they update elements without using innerHTML. In the docs, they clearly state how they're better than other templating engines because they don't re-render with innerHTML (ctrl-f innerHTML -- sorry). I started poking through the source code but there's a LOT of it and was hoping that perhaps I could get a faster answer from you guys.
So far my guesses have been
{{test}}
into something like <ng-bind>test</ng-bind>
which the linker can update when data changes, but it doesn't seem like this is happening when I look at the DOM of a rendered Angular page. And also seems like it could interfere with a client's CSS and other javascript components external to Angular. <ng-bind></ng-bind>
tag).If anyone knows I'd love to learn. Otherwise it's back to the source code for me.
EDIT New Guess
After thinking about it some more, I believe this might be what happens: Compiler swallows html, 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>
Then Angular can crawl through and index all angular text nodes ( {{model}}
) eg document.getElementsByClass('ng-binding')[0].childNodes[0]
. Each stored node can then be associated by the linker with a scoped model $scope['model']
. Each node can then be updated extremely quickly by setting node.nodeValue = $scope['somemodel
] (simplified)` and voilà, technically no innerHTML'ing and lightning speed DOM updates.
Upvotes: 4
Views: 1824
Reputation: 123513
Rather than replacing the element itself, as innerHTML
would do, Angular prefers to modify the properties of existing elements.
The ng-bind
directive is actually a good example. It keeps a reference to the element
and just updates its .text()
as the $scope
changes (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 doesn't necessarily mean Angular won't use innerHTML
at times, especially when creating new content. But, it tries to avoid it when possible.
Upvotes: 5