The official answer is that you use
trackBy to avoid recreating elements in the DOM for new instances of objects that have the same identifier.
On the face of it, your setup doesn't prove that
ngFor isn't just ignoring the
undefined value you are returning in
trackByFn and recreating the DOM elements anyway when new instances appear in the model.
New items with the same id as existing objects may have had other properties changed, so you would expect the HTML to be correct regardless of whether or not you use (or mis-use)
I created a test environment using your code, except I forked the source code for
*ngFor so that I could add my own logging to trace what happens inside
I tested three scenarios:
trackByFn returns the unique id
C) does't use
I traced what happens in each scenario for the following steps
- create list
- partially replace some list data
- sort list
- reset list data
2020欧洲杯时间表I assigned new instances of objects at each step for a "pure" test.
1. create list
The same for all 3 scenarios - a DOM element is created for each item in the list.
2. partially replace some list data
2020欧洲杯时间表A) removes DOM elements for removed items and creates new DOM elements for new items. All elements are updated.
2020欧洲杯时间表B) creates new DOM elements for items with an index out of the bounds of the original array. All elements are updated.
2020欧洲杯时间表C) recreates all DOM elements.
3. sort list
2020欧洲杯时间表A) moves the DOM elements that have moved positions
B) updates the DOM elements that have moved positions
C) recreates all DOM elements
4. reset list data
2020欧洲杯时间表A) removes DOM elements for removed items and creates new DOM elements for new items. All elements are updated (same as scenario 2).
B) removes DOM elements for removed items. All elements are updated.
C) recreates all DOM elements.
It is important to note that these tests were done using new instances of objects.
*ngFor is more efficient if you are reusing object references.
trackBy2020欧洲杯时间表 is more efficient in terms of DOM manipulation if you have a very volatile list.
The surprising result
From my tests it appears that your example does less DOM manipulation than when returning the unique identifier from
trackByFn2020欧洲杯时间表. If you replace 3 items with 3 new items, your method wouldn't do any DOM manipulation and would still run the same update method as the "proper" way. The "proper" method would remove the original 3 DOM elements and add 3 new DOM elements.
This suggests that we could just provide a
trackByFn that returns a constant value without any unexpected results. From having looked through the source code and played around with it, I can't see how this is a problem (aside from confusing other people who look at your code).
This does make me wonder why the default implementation has to recreate all of the DOM elements, when reusing old DOM elements seems to work just fine. I'm sure there are some cases that I've not considered, and I would love to hear them.
This turned into a bit of "fun" research task rather than a definitive answer, but hopefully it proves useful. Even though I've shown that returning a constant value from
trackByFn2020欧洲杯时间表 seems to be the most performant option, I'd still be hestitant about using this approach in production code. Even if it works for all cases now I wouldn't be surprised if it were to be "fixed" at some point as a bug.
ngForOf source code: