I'm calling a component recursively in accordion to show tree like structure.
The code is working for short input but it is lagging on recursive calls for nested data
It is just like a json tree.
//sample.component.html
<app-tree [input]="data"></app-tree>
//tree.component.html
<mat-accordion>
<mat-expansion-panel hideToggle="true" (click)="toggleTree($event, input)">
<mat-expansion-panel-header>
<mat-panel-title>
<mat-icon>{{input.buttonName}}</mat-icon>
{{input.key}}
</mat-panel-title>
</mat-expansion-panel-header>
<ul class="main-obj"> // tried *ngIf here
<div class="obj-list" *ngFor="let item of input.value; trackBy: trackChanges">
<li>
{{item.key}}: {{item.value}}
</li>
<li style="list-style: none; margin-left: -40px;">
<app-tree [input]="item"></app-tree>
</li>
</div>
</ul>
</mat-expansion-panel>
</mat-accordion>
//tree.component.ts
import { Component, OnInit, Input, Output } from '@angular/core';
import { EventEmitter } from 'events';
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.css']
})
export class TreeComponent implements OnInit {
@Input() input: any;
@Output() click = new EventEmitter();
constructor(){}
ngOnInit(){
}
toggleTree(event, toggleButton) {
event.stopPropagation();
if(toggleButton.buttonName == 'add')
toggleButton.buttonName = 'remove';
else
toggleButton.buttonName = 'add';
};
trackChanges = (index) => {
return index;
}
}
I've tried placing ngIf (as shown in the code before ngFor) but is not that much effective.
Is there any way to load component when opening accordion?
Thanks!
Answering to your question:
Is there any way to load component when opening accordion?
Yes, there is, but I'm not sure it's gonna solve a lagging problem. Anyway, try to wrap the expansion panel's content in a ng-template
containing the matExpansionPanelContent
attribute. It'll lazy load its content (see the docs).
<mat-accordion>
<mat-expansion-panel hideToggle="true" (click)="toggleTree($event, input)">
<mat-expansion-panel-header>
<mat-panel-title>
<mat-icon>{{input.buttonName}}</mat-icon>
{{input.key}}
</mat-panel-title>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<ul class="main-obj"> // tried *ngIf here
<div class="obj-list" *ngFor="let item of input.value; trackBy: trackChanges">
<li>{{item.key}}: {{item.value}}</li>
<li style="list-style: none; margin-left: -40px;">
<app-tree [input]="item"></app-tree>
</li>
</div>
</ul>
</ng-template>
</mat-expansion-panel>
</mat-accordion>