<script type="text/html" id="tree-node">
<li>
<i data-bind="css: {'icon-collapse-alt': expanded, 'icon-expand-alt': collapsed}, click: toggle"></i>
<span data-bind="text: name, click: $root.selected"></span>
<div data-bind="if: expanded">
<ul data-bind="template: {name: 'tree-node', foreach: children}"></ul>
</div>
</li>
</script>
Then you place the tree view in your HTML like this:<ul data-bind="template: {name: 'tree-node', data: root}"></ul>
And of course you need a view model for the tree:
function TreeNode(values) {
var self = this;
ko.mapping.fromJS(values, { children: { create: createNode }}, this);
this.expanded = ko.observable(false);
this.collapsed = ko.computed(function() {
return !self.expanded();
})
}
TreeNode.prototype.toggle = function () {
this.expanded(!this.expanded());
};
function createNode(options) {
return new TreeNode(options.data);
}
var root = new TreeNode({ id: "1", name: "Root", children: [
{ id: "1.1", name: "Node 1", children: [
{id: "1.1.1", name: "Node 1.1", children: []},
{id: "1.1.2", name: "Node 1.2", children: []}
]},
{ id: "1.2", name: "Node 2", children: []}
]});
var viewModel = {
root: root,
selected: ko.observable()
};
ko.applyBindings(viewModel, $('html')[0]);
You can try this example live in this Plunkr.