The API I am working against gives me the following structure in response:
"data": [
{
"id": 5,
"name": "First name",
"parent": 0
},
{
"id": 1,
"name": "Second name",
"parent": 5
},
{
"id": 6,
"name": "Third name",
"parent": 1
},
{
"id": 15,
"name": "Fourth name",
"parent": 0
},
{
"id": 25,
"name": "Fifth name",
"parent": 5
}
]
I would like to build a tree structure around this using ngFor
that supports an unlimited number of children levels.
This is what I have tried so far:
<div *ngFor="let d1 of _dataList">
<ul *ngIf="d1.parent == 0">
<li>
{{d1.name}}
<ul *ngFor="let d2 of _dataList">
<li *ngIf="d2.parent == d1.id">{{d2.name}}</li>
</ul>
</li>
</ul>
</div>
That works, but it's ugly and I have to manually repeat this X-levels down the data and thus leaving a hard-coded limit.
How can one optimize this code to support unlimited levels - and look better?
https://stackblitz.com/edit/angular-yij5e5?file=src%2Fapp%2Ftree-view%2Ftree-view.component.ts Note: below code is not recursive it is 2d and can't use for tree render. you should use ng template or defining a component for it.
<div *ngFor="let d1 of _dataList">
<ul *ngIf="d1.parent == 0">
<li>
{{d1.name}}
<ul *ngFor="let d2 of _dataList">
<li *ngIf="d2.parent == d1.id">{{d2.name}}</li>
</ul>
</li>
</ul>
</div>
let xTree = [{
"id": 5,
"name": "First name",
"parent": 0
},
...
];
let tree = [{
id: 0,
name: 'root',
parent: null,
childs: []
}];
let todoList = [];
Converter();
function FindParent(list, el) {
if (list.length > 0) {
let res = list.find(x => x.id === el.parent);
if (res) {
return res;
} else {
let _res = undefined;
list.forEach(xchild => {
_res = FindParent(xchild.childs, el);
if (res)
return _res;
});
return _res
}
} else {
return undefined;
}
}
function Converter() {
todoList = xTree;
for (let x = 0; x < 90; x++) {
todoList.forEach(r => {
let parent = FindParent(tree, r);
if (parent) {
if (!parent.childs) {
parent.childs = [];
}
parent.childs.push(r);
todoList = todoList.filter(el => el !== r);
}
});
}
}
<ul class="tree">
<ng-template #recursiveList let-list="list">
<li *ngFor="let item of list">
{{item.name}}
<ul *ngIf="item.childSet.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ list: item.data}"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="recursiveList; context:{ list: data}"></ng-container>
</ul>
ul.tree, ul.tree ul {
list-style-type: none;
}
ul.tree, ul.tree ul {
list-style-type: none;
background: url(/assets/vline.png) repeat-y;
margin: 0;
padding: 0;
}
ul.tree ul {
margin-left: 10px;
}
ul.tree li {
margin: 0;
padding: 0 12px;
line-height: 20px;
background: url(/assets/node.png) no-repeat;
color: #369;
font-weight: bold;
}
ul.tree li:last-child {
background: #fff url(/assets/lastnode.png) no-repeat;
}
you can have a recusive component, say the component called TreeComponent
and the template for TreeComponent
will be like this
<div *ngFor="let item of dataList">
<ul *ngIf="item.parent==parentId">
<li>{{item.name}}
<tree [parentId]="item.id" [dataList]="removeCurrentLevelItems(dataList,parentId)"></tree>
</li>
</ul>
</div>
check the link here for a live demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With