Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

ng-repeat track by $index with custom directive #16332

Closed
1 of 3 tasks
michael-letcher opened this issue Nov 15, 2017 · 3 comments · Fixed by #16397
Closed
1 of 3 tasks

ng-repeat track by $index with custom directive #16332

michael-letcher opened this issue Nov 15, 2017 · 3 comments · Fixed by #16397

Comments

@michael-letcher
Copy link

michael-letcher commented Nov 15, 2017

I'm submitting a ...

  • bug report
  • feature request
  • other

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:

  1. create ng repeat with a custom directive inside (include track by $index)
  2. using $filter on the repeat array filter the array and you will notice the data in the directive will not reflect the new filtered array

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

@frederikprijck
Copy link
Contributor

frederikprijck commented Nov 15, 2017

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.

https://plnkr.co/edit/dxzgjmE5MEA0bwQdckVS?p=preview

@gkalpak
Copy link
Member

gkalpak commented Nov 15, 2017

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 😁
@michael-letcher, would you be interested in submitting a PR to improve the docs?

@390339781
Copy link

what

Narretz added a commit to Narretz/angular.js that referenced this issue Jan 9, 2018
- deduplicate info between docs section and arguments
- don't draw too much attention to track by  ...
- ... but highlight its drawbacks when used with one-time bindings
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes angular#16332
Closes angular#16334
Narretz added a commit that referenced this issue Jan 17, 2018
- deduplicate info between docs section and arguments
- don't draw too much attention to track by $index  ...
- ... but highlight its drawbacks
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes #16332
Closes #16334 
Closes #16397
Narretz added a commit to Narretz/angular.js that referenced this issue Jan 17, 2018
- deduplicate info between docs section and arguments
- don't draw too much attention to track by $index  ...
- ... but highlight its drawbacks
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes angular#16332
Closes angular#16334 
Closes angular#16397
Narretz added a commit that referenced this issue Jan 17, 2018
- deduplicate info between docs section and arguments
- don't draw too much attention to track by $index  ...
- ... but highlight its drawbacks
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes #16332
Closes #16334 
Closes #16397
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants