I'm submitting a ...
Current behavior:
After filtering and array that is being repeated and has a custom directive in each repeated element that has an isolated scope. The custom directive is not reinitiated.
I assume this is expected behaviour but can be confusing and should be made clearer as to what putting track by $index
can do to your custom directives.
Expected / new behavior:
NA
Minimal reproduction of the problem with instructions:
AngularJS version: 1.5.10
Browser: all
Anything else:
Could the docs be made more clear between the what Angular is doing when using track by
and that using $index
with custom directives is not going to work.
Check my response here for a break down of the issue
https://stackoverflow.com/a/47310734/2536454
Any chance u can be a bit more specific (or provide a reproduction sample)?
You can start from this plunkr to reproduce the problem, as it seems to work fine for me.
I believe this is indeed expected behavior. Quoting the docs:
When items are reordered, their respective templates are reordered in the DOM.
To minimize creation of DOM elements, ngRepeat uses a function to "keep track" of all items in the collection and their corresponding DOM elements. For example, if an item is added to the collection, ngRepeat will know that all other items already have DOM elements, and will not re-render them.
In such cases (when using
track by $index
), the nth DOM element will always be matched with the nth item of the array, so the bindings on that element will not be updated even when the corresponding item changes, essentially causing the view to get out-of-sync with the underlying data.
Putting it all together, what happens is that tracking by $index
, tells ngRepeat
that the first item is always the same (since it has the same index). ngRepeat
does not know there underlying data has changed, because you tell it that as long as the index is the same, the item is the same (in prractice, tracking by $index
is rarely useful).
Since ngRepeat
things that the item is the same, it will not re-create the DOM, but keep the existing one (bound to the existing scope etc). And therefore any directives that appear on the tempate will not be re-compiled (since compilation/linking happens only when "stamping out" a new instance).
But I admit we are not doing a terribly good job explaining that in the docs :grin:
@michael-letcher, would you be interested in submitting a PR to improve the docs?
what
Most helpful comment
I believe this is indeed expected behavior. Quoting the docs:
Putting it all together, what happens is that tracking by
$index
, tellsngRepeat
that the first item is always the same (since it has the same index).ngRepeat
does not know there underlying data has changed, because you tell it that as long as the index is the same, the item is the same (in prractice, tracking by$index
is rarely useful).Since
ngRepeat
things that the item is the same, it will not re-create the DOM, but keep the existing one (bound to the existing scope etc). And therefore any directives that appear on the tempate will not be re-compiled (since compilation/linking happens only when "stamping out" a new instance).But I admit we are not doing a terribly good job explaining that in the docs :grin:
@michael-letcher, would you be interested in submitting a PR to improve the docs?