I have a tree structure shamelessly acquired from building a treeview in aurelia
This works great when I push nodes onto the tree. What I would like to do is parse a json object and push that onto the tree. This partly works, as the tree is rendered but I am unable to expand / collapse nodes that have children. I believe this is due to a call to hasChildren being a method and not a property and possibly deep binding. I have tried changing this method to a get property but don't seem to be able to get this to work.
Node Model Class
export class NodeModel {
public name: string;
public visible: boolean;
public children: NodeModel[];
public expanded: boolean;
public icon: string;
constructor(name: string, children: NodeModel[])
{
this.name = name;
this.children = children || [];
this.visible = true;
if (this.hasChildren()) {
this.icon = "fa fa-chevron-down";
this.expanded = true;
}
}
hasChildren(): boolean {
return this.children.length > 0;
}
toggleNode(): void {
for (var i: number = 0; i < this.children.length; i++) {
this.children[i].visible = !this.children[i].visible;
}
this.expanded = !this.expanded;
if (this.expanded === true) {
this.icon = "fa fa-chevron-down";
} else {
this.icon = "fa fa-chevron-right";
}
}
}
Treeview VM
import {NodeModel} from "node-model";
export class T {
private locations: NodeModel[];
constructor() {
this.locations = [];
var texas = new NodeModel('Texas',
[new NodeModel('Houston', []),
new NodeModel('Austin', [])]);
console.log(JSON.stringify(texas));
this.locations = [texas];
}
addCardiff(): void {
var cardiff = new NodeModel('Cardiff',
[new NodeModel('Cardiff Bay', [])]);
this.locations.push(cardiff);
}
addBristol(): void {
var bristol = `{"name":"Bristol","children":
[{"name":"Easton","children":[],"visible":true},
{"name":"Eastville","children":[],"visible":true}],
"visible":true,"icon":"fa fa-chevron-down","expanded":true}`;
var d = JSON.parse(bristol);
this.locations.push(d);
}
}
Tree node component
import {bindable} from 'aurelia-framework';
export class TreeNode {
@bindable current = null;
}
Tree node component view
<template>
<ul show.bind="current.visible" style="list-style-type: none;">
<li>
<div>
<span if.bind="current.hasChildren()" click.trigger="current.toggleNode()" class="${current.icon}"></span>
<span>${current.name}</span>
</div>
<tree-node repeat.for="node of current.children" current.bind="node"></tree-node>
</li>
</ul>
</template>
view
<template>
<require from="tree-node"></require>
<tree-node repeat.for="node of locations" current.bind="node"></tree-node>
<button click.trigger="addCardiff()" class="btn btn-default">Add Cardiff</button>
<button click.trigger="addBristol()" class="btn btn-default">Add Bristol</button>
</template>
Output below
Any ideas would be greatly appreciated.
Regards
Mike
