Given the input data
+-------+---------+
| node | subnode |
+-------+---------+
| 3 | 6 |
| 3 | 7 |
| 3 | 8 |
| 3 | 9 |
| 6 | 8 |
| 7 | 9 |
| 9 | 8 |
+-------+---------+
e.g. as a 2D array:
const tree = [
[3, 6],
[3, 7],
[3, 8],
[3, 9],
[6, 8],
[7, 9],
[9, 8]
];
describing this tree:
3
├─ 6
│ └─ 8
├─ 7
│ └─ 9
│ └─ 8
├─ 8
└─ 9
└─ 8
How to implement an Angular solution to show this on a web page let's say as nested <div>
s like
<div id="node3" style="padding-left:2em">3<div id="node6" [...]</div>
? Illustration:
Günter Zöchbauer linked his solution which works well for simple cases where the tree view is "passive", so it is only to visualize some data as a static element.
However, if there should be communication between the tree in the template and the component (e.g. a node has a (click)
event that calls a method defined in the component), due to the fact that Günter's solution uses recursively self-contained components each node having its own directive, one might face issues:
Handling the tree as a whole from the component is made difficult because of multiple scopes created by the repetition of the component. (- Correct me if I'm wrong.)
That's why I needed another solution which is template-only and this way not causing the component to be replicated for each node. Here it is:
In the .ts:
const nodes = [{
number: 3,
children: [{
number: 6,
children: [{
number: 8,
children: []
}]
}, {
number: 7,
children: [{
number: 9,
children: [{
number: 8,
children: []
}]
}]
}, {
number: 8,
children: []
}, {
number: 9,
children: [{
number: 8,
children: []
}]
}]
}];
In the .html:
<ng-template #recursion let-nodes>
<div style="margin-left:2em" *ngFor="let node of nodes">
{{node.number}}
<ng-container *ngIf="node.children.length > 0">
<ng-container *ngTemplateOutlet="recursion;
context:{ $implicit: node.children }"></ng-container>
</ng-container>
</div>
</ng-template>
<ng-container *ngTemplateOutlet="recursion;
context:{ $implicit: nodes }"></ng-container>
P.S.: See these answers on how to convert tree
to nodes
.