Reputation: 3433
I have a dataset like that:
[
{
prop1: "",
prop2: "",
child: [
prop1: "",
prop2: "",
child: [
...
]
]
},
{
prop1: "",
prop2: "",
child: [
prop1: "",
prop2: "",
child: [
...
]
]
}
],
[
{
prop1: "",
prop2: "",
child: [
prop1: "",
prop2: "",
child: [
...
]
]
},
{
prop1: "",
prop2: "",
child: [
prop1: "",
prop2: "",
child: [
...
]
]
}
],
This can go deeper forever, it is not a two or three-dimensional array. It is an N-dimensional array. I was thinking of how to properly iterate it in the HTML, but using nested ngFor would be a suicide and kinda impossible since, as I said, I don't know how many nested children I will have.
What I want is a tree view of that dataSet.
What could be a good solution to this?
Upvotes: 0
Views: 610
Reputation: 813
You can use a recursive component, let call it displayobject. For each level, the displayobject component list the properties, if the property is a string then it displays it, otherwise it loads a new displayobject component that do the same thing with the given object.
Template :
<div *ngFor="let property of propertyList">
<span *ngIf="isString(myObject[property])">
{{ property }}
</span>
<displayobject *ngIf="isObject(myObject[property])" [myObject]="myObject[property]">
</displayobject>
</div>
Component :
import { Component, Input } from '@angular/core';
@Component({
selector: 'displayobject',
...
})
export class DisplayObject {
@Input() myObject;
public propertyList = [];
ngOnChanges() {
this.propertyList = Object.keys(this.myObject);
}
}
And you call it :
<displayobject [myObject]="yourObject"></displayobject>
Upvotes: 2
Reputation: 1051
Following @Noelmout solution but getting in a simpler way.
The idea is the set a recursive component.
Since the data set you just shown satisfies a pattern like {prop1: "", prop2: "", child: [...]}
and so on. Consider a component to render recursively and typed.
*.ts
type Item = {
prop1: string,
prop2: string,
child: Item[];
}
@Component({
selector: 'item-display',
templateUrl: './item-display.html',
styleUrls: ['./item-display.component.scss']
})
export class ItemDisplayComponent {
@Input() item: Item;
}
*.html
<div class="content">
<div class="prop1">{{ item.prop1 }}</div>
<div class="prop2">{{ item.prop2 }}</div>
<div class="child" *ngFor="let c of item.child">
<item-display [item]="c"></item-display>
</div>
</div>
Now, you can modify anything on the component that will be applied to all the nested components.
Even more, add a depth
attribute, if needed
...
@Input() depth: number = 0; // or 1, up to you
<item-display [item]="c" [depth]="depth + 1"></item-display>
And finally, since you have a collection of that items, from you root component
<div class="item-display" *ngFor="let item of rootItems">
<item-display [item]="item"></item-display>
</div>
No need to set the depth property because has a default value (and better off not to expose that property, it is like a internal field just know by ItemDisplayComponent
).
Upvotes: 2