Components: [mat-tree] Nodes are not updated correctly with trackyBy function set

Created on 1 Jun 2018  路  5Comments  路  Source: angular/components

Bug, feature request, or proposal:

MatTree does not reflect the changes to the nodes if trackBy function is used. For example, I have several items with trackBy function pointing to their "id" property. If I provide a new array with completely same ids, but with changes to some of the other properties, change detection does not occur.

What is the expected behavior?

When used with trackBy function MatTree should trigger change detection on all nodes, just like ngFor with trackBy does.

What is the current behavior?

No changes are detected therefore data is not updated in template.

What are the steps to reproduce?

https://stackblitz.com/edit/angular-material2-issue-z8ubtt

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Latest versions of Angular, Material (check StackBlitz). Any browser.

Is there anything else we should know?

Same issue was observed last year with MatTable.

P4 cdtree

Most helpful comment

@schuchard , however, the way of how treeTracker works is different with the trackBy of *ngFor. *ngFor will update the item if the item can be identified as same item (but item properties may be changed) by TrackBy. The purpose of trackBy is only for performance by not destroying an item's dom if it's just has some property changes.

All 5 comments

use forEachIdentityChange method in differ to track identity changes like as ngFor do?

Still happening, any news?

@andrewseguin Can you take a look since it looks like most of the logic for this is reused between the Table and Tree

I think the behavior in your stackblitz is working as expected. You're telling the trackBy function to track each change based on the id value. The initial value and the next value both have and id === 1 so the Tree doesn't see any changes.

If you change your tracking function to either of these it works.

treeTracker = (index, person) => person;
treeTracker = (index, person) => person.id + person.name;

or if the id changes for the button action, the tree updates
ts changeName() { this.dataSubject.next([{id: 2, name: 'Kara', expandable: false, level: 0}]); }

@schuchard , however, the way of how treeTracker works is different with the trackBy of *ngFor. *ngFor will update the item if the item can be identified as same item (but item properties may be changed) by TrackBy. The purpose of trackBy is only for performance by not destroying an item's dom if it's just has some property changes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RoxKilly picture RoxKilly  路  3Comments

julianobrasil picture julianobrasil  路  3Comments

Hiblton picture Hiblton  路  3Comments

savaryt picture savaryt  路  3Comments

dzrust picture dzrust  路  3Comments