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

custom directive inside ng-repeat doesn't update once using track by index #15363

Closed
ramseyfeng opened this issue Nov 4, 2016 · 6 comments
Closed

Comments

@ramseyfeng
Copy link

It seems the custom directive used in the ngRepeat with "track by index" will not got update?
I have create a plunk for this:

http://plnkr.co/edit/MBleogyCukFh4WEZWCts?p=preview

Once you remove the "track by index", everything works fine!

If it is not a bug, please guide me where the doc has introduced this part. Thanks!

@Narretz
Copy link
Contributor

Narretz commented Nov 4, 2016

@gkalpak is great at explaining this behavior. We should put it in the docs somehow ...

@gkalpak
Copy link
Member

gkalpak commented Nov 4, 2016

This is expected behavior for track by $index. The point of tracking items is to re-use the same DOM element + scope for the same item, so Angular doesn't have to go through the whole compiling/linking cycle for tracked elements. From the docs:

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.

The default tracking function (which tracks items by their identity) does not allow duplicate items in arrays. This is because when there are duplicates, it is not possible to maintain a one-to-one mapping between collection items and DOM elements.

[...]

Should you reload your data later, ngRepeat will not have to rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones.

So, by using track by $index, you are telling Angular that the nth list item is always the same (because it's index is always n), so it will not create and new DOM element, compile the template, create a new scope, link the element with the scope etc. It will re-use the already compiled/linked nth DOM element for the nth list item (even if the list changes).

That's what tracking by $index is about.

@gkalpak gkalpak closed this as completed Nov 4, 2016
@ramseyfeng
Copy link
Author

@gkalpak Thanks for the explaination! :)

@luncht1me
Copy link

luncht1me commented Aug 3, 2017

Using track by, any custom scope manipulation I did in a directive's link function, gets removed when the element is recycled. ie: a list of articles on a page, change up the filtering for the list and any instances that existed between the two now have custom scope properties removed that were generated in the original run of the link function. So... seems to me that angular isn't preserving the scope when using track by :(

@olivezz
Copy link

olivezz commented Jul 16, 2018

@ramseyfeng Thank you so much you saved me, It told me the whole day to fix this, when I removed the "track by index" it works fine.

@ramseyfeng
Copy link
Author

@olivezz np :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants