Greetings, dear reader.
If your goal is to display a tree structure on the DOM using Aurelia, there are several options available to achieve this task effectively.
Given that this is a recursive structure, it makes sense to define it as such. Here's an example (assuming Typescript and bootstrap):
export interface TreeNode {
name: string;
children?: TreeNode[];
}
To render the tree, one approach is to create a Custom component for the "Tree" itself and another custom component to handle the rendering of individual nodes in a recursive manner.
You can proceed as follows:
<require from="./tree"></require>
...
<tree source.bind="treeData"></tree>
An example of the treeData could be:
treeData: TreeNodeModel[] = [
{ name: "node01", children: [{ name: "child011" }, { name: "child012" }, { name: "child013" }] },
{ name: "node02", children: [{ name: "child021" }, { name: "child022", children: [{ name: "child0221" }, { name: "child0222" }, { name: "child0223" }] }] },
{ name: "node03", children: [{ name: "child031" }] },
{ name: "node04", children: [{ name: "child041" }] },
{ name: "node05", children: [{ name: "child051" }] },
{ name: "node06", children: [{ name: "child061" }] },
{ name: "node07", children: [{ name: "child071" }] },
The Tree custom component implementation would look like this:
import { bindable } from "aurelia-framework";
import { TreeNodeModel } from "./model";
export class Tree {
@bindable source: TreeNodeModel[];
}
And here is the view for the Tree custom component:
<template>
<require from="./node"></require>
<div class="container">
<div repeat.for="node of source">
<node node.bind="node"></node>
</div>
</div>
</template>
Next, we have the Node custom component:
import { bindable } from "aurelia-framework";
import { TreeNodeModel } from "./model";
export class Node {
@bindable node: TreeNodeModel;
@bindable indent: number = 0;
}
The corresponding view for the Node component would be:
<template>
<div style="margin-left: ${indent * 8}px;">
<div>${node.name}</div>
<div repeat.for="child of node.children">
<node node.bind="child" indent.bind="indent + 1"></node>
</div>
</div>
</template>
If you want to see a working example with all the code, please visit this link. Enjoy exploring this solution!
Wishing you success with your project.