6

I have an *ngFor directive used on an array of objects, which have quite a lot of properties.

I would like this *ngFor to be updated only when three of these properties are changed, but according to the documentation on TrackByFunction, there isn't a valid example of how to achieve that.

I tried to return an object with the properties in it, but it doesn't seem to work, as the template still gets rendered again when any other property is changed.

Supamiu
  • 8,501
  • 7
  • 42
  • 76
  • **Premature Optimization is the Root of All Evil** optimize only when the rendering is slow. – G.Vitelli Dec 02 '17 at 09:40
  • @G.Vitelli I'm optimizing because it's slow, due to the fact that the array can be quite big and I can't add pagination, so I have to optimize node deletion/creation by removing such operations when they aren't needed. – Supamiu Dec 02 '17 at 11:36

3 Answers3

5

Try add [ngForTrackBy]="trackSelectionsBy" to your element and your trackSelectionsBy method should look something like this:

public trackSelectionsBy(index: number, myObject: MyObject): any {
    return myObject.id + myObject.count + myObject.startTime;
}

And add your own properties to track by.

Kungen
  • 607
  • 1
  • 11
  • 24
2

I know this is old but the issue I think is how you handle the response to the tracking comparator. In your example you reply with another object which when compared to another object will always return as different.

So every time you make the object {a: "ehhhh", b:"bee", c:"cee"} because it has your limited set of properties, then compare it to another object even though the property values are the same they are not the same object.

If you returned JSON.stringify(trackedObj) then the two strings compared could return the boolean value needed to trigger change detection properly. But at that point I wonder what level of improvement the string conversion is over the standard, except it would allow items that didn't change to not be removed from the dom.. Interesting idea...

A Bit more detail in another SO: https://stackoverflow.com/a/1144249/1251604

Dennis Smolek
  • 8,480
  • 7
  • 30
  • 39
  • I figured this by myself few months ago but it's totally what you're saying, so I'll accept the answer for people who will come here using google, so they know the real answer. – Supamiu Jul 20 '18 at 10:06
1

I had a very similar situation with a very large array and could not add pagination, could not find any solution to use multiple properties with trackByFn and I had three properties and four different scenarios where they could change. I solved this particular problem using an additional property in my object called uniquefier (a UUID) which I then updated with a new UUID when any of the three properties or four different scenarios occurred. I then added this property to my trackByFn. Hope this helps.

Neil Stevens
  • 3,534
  • 6
  • 42
  • 71