How does ngRepeat optimize the compile function?
-
21-12-2019 - |
Domanda
via odetocode:
The idea behind the compilation step is to allow for one time DOM manipulation before the cloning – a performance optimization. [plunk]
So... when a directive is placed inside of an ng-repeat
block, it is being instantiated multiple times, but the compile function only executes one times. How does ngRepeat implement this optimization?
Soluzione
The AngularJS docs have a neat example of what you ask:
Hello {{user}}, you have these actions:
<ul>
<li ng-repeat="action in user.actions">
{{action.description}}
</li>
</ul>
The documentation says:
...the template
<li>
element needs to be cloned and inserted into ul. But cloning the<li>
element is not enough. It also needs to compile the<li>
so that its directives, like{{action.description}}
, evaluate against the right scope.
So this is how ngRepeat
does it:
ngRepeat
works by preventing the compilation process from descending into the<li>
element so it can make a clone of the original and handle inserting and removing DOM nodes itself.Instead the
ngRepeat
directive compiles<li>
separately. The result of the<li>
element compilation is a linking function which contains all of the directives contained in the<li>
element, ready to be attached to a specific clone of the<li>
element.At runtime the
ngRepeat
watches the expression and as items are added to the array it clones the<li>
element, creates a new scope for the cloned<li>
element and calls the link function on the cloned<li>
.
So, to summarize:
The element with
ngRepeat
gets compiled byngRepeat
itself, resulting in a linking functions that contains all other directives on the element (in this case, the interpolation directive foraction.description
)When items are added to
user.actions
, the element is cloned and gets a new scope, and the linking function is called on it.
Altri suggerimenti
It is not an optimization of ngRepeat
- it is the same for every Angular directive (both built-in and custom).
The template is compiled once for every instance of your directive in your HTML template (but may be cloned or linked multiple times).
E.g. in
<ul>
<li ng-repeat="action in user.actions">...</li>
</ul>
ngRepeat
will compile <li ng-repeat="action in user.actions">...</li>
once and then clone and link it multiple times (one for every action
that is found in user.actions
).