I am trying to dynamically load the children when the user expands a node.
The issue is when I populate the children array, mat-tree is not displaying the children. If I display the same data using simple *ngFor, when the children array has elements added, it shows them.
I have a working example here: stackblitz example This is the code and html
ts
import {NestedTreeControl} from '@angular/cdk/tree';
import {Component} from '@angular/core';
import {MatTreeNestedDataSource} from '@angular/material/tree';
export class PropertyLevel {
constructor(
public code : string,
public hasSubLevels: boolean,
public subproperties : PropertyLevel[]
){}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
nestedTreeControl: NestedTreeControl<PropertyLevel>;
nestedDataSource: MatTreeNestedDataSource<PropertyLevel>;
constructor() {
this.nestedTreeControl = new NestedTreeControl<PropertyLevel>(this._getChildren);
this.nestedDataSource = new MatTreeNestedDataSource();
this.nestedDataSource.data = [
new PropertyLevel( '123', false, []),
new PropertyLevel( '345', true, [
new PropertyLevel( '345.a', false, null),
new PropertyLevel( '345.b', true, []),
]),
new PropertyLevel( '567', false,[]),
];
}
hasNestedChild = (_: number, nodeData: PropertyLevel) => nodeData.subproperties;
private _getChildren = (node: PropertyLevel) => node.subproperties;
expandToggle(node: PropertyLevel, isExpanded: boolean): void {
if (node.subproperties && node.subproperties.length == 0) {
if(node.code == '123') {
node.subproperties.push(new PropertyLevel('123.a', false, null))
}
else if(node.code == '567') {
node.subproperties.push(new PropertyLevel('567.a', false, null));
node.subproperties.push(new PropertyLevel('567.b', false, null));
node.subproperties.push(new PropertyLevel('567.c', false, null));
}
}
}
}
html
<mat-tree [dataSource]="nestedDataSource" [treeControl]="nestedTreeControl" class="example-tree">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
<li class="mat-tree-node">
<button mat-icon-button disabled></button>
{{node.code}}
</li>
</mat-tree-node>
<mat-nested-tree-node *matTreeNodeDef="let node; when: hasNestedChild">
<li>
<div class="mat-tree-node">
<button mat-icon-button matTreeNodeToggle
(click)="expandToggle(node, nestedTreeControl.isExpanded(node))"
[attr.aria-label]="'toggle ' + node.filename">
<mat-icon class="mat-icon-rtl-mirror">
{{nestedTreeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.code}}
</div>
<ul [class.example-tree-invisible]="!nestedTreeControl.isExpanded(node)">
<ng-container matTreeNodeOutlet></ng-container>
</ul>
</li>
</mat-nested-tree-node>
</mat-tree>
<div>
<ul>
<li *ngFor="let node of nestedDataSource.data">
{{node.code}}<br />
<ul>
<li *ngFor="let subnode of node.subproperties">
{{subnode.code}}
</li>
</ul>
</li>
</ul>
</div>