4

We are kicking a new project using angularJS :) and one of the requirements is a tree control. The tree control should support "Lazy Loading", So we could add nodes to it dynamically as we get more data using AJAX.

I saw the 2 directives below, but I do not think "Lazy Loading" is supported so before I start developing it myself I am asking you folks :)

The 2 nice tree directives I saw:

https://github.com/eu81273/angular.treeview/blob/master/angular.treeview.js https://github.com/nickperkinslondon/angular-bootstrap-nav-tree

Thanks, Avi

Avi Kessel
  • 96
  • 1
  • 9

1 Answers1

1

Because AngularJS loads directives before any logic, you cannot use them very well for recursive operations, else you probably wouldn't need a directive for one in the first place.

However, one very pleasant workaround is using ng-include, as this doesn't have the above limitation. And then making a tree is extremely simple.

Where you want to tree, you have something like

    <ul class="tree-container">
        <li style="margin: 5px; list-style: none;" ng-repeat="d in vm.features" ng-include="'tree_item_renderer.html'"></li>
    </ul>

then the include looks something like this

<script type="text/ng-template" id="tree_item_renderer.html">
    <span ng-click="d.expand = !d.expand;vm.getChildNodes(d)" ng-show="!d.expand && d.hasChildren"><i class="fa fa-fw fa-plus-circle"></i></span>
    <span ng-show="d.expand && d.hasChildren" ng-click="d.expand = !d.expand;d.children=null" ><i class="fa fa-fw fa-minus-circle"></i></span> 
    <span ng-show="!d.hasChildren" style="margin-left:28px"></span>

    <ul>
        <li style="list-style:none;" ng-repeat="d in d.children" ng-model="d" ng-include="'tree_item_renderer.html'"></li>
    </ul>
</script>

In the controller vm.getChildNodes(d) call you can get the children for the currently expanded node. I expand the nodes and then actually asynchronously do a count for each node over odata to determine if the node has children, so I can show if one of the children has children of its own, but of course you could more efficiently track that in the database if you have control over that (I think I will update my model for this myself).

Note that I've implemented it so that if you open and close and then open, it actually reloads the nodes. You don't have to do that of course, but it saves me from having to implement a reload/refresh button otherwise and it's not like users are going to open/close trees over and over because they have nothing better to do. ;)

The added advantage I have is that I implement user input for some (most) of the nodes, e.g. select them, enter a value for them. I've noticed it is more efficient if these only exist 'on demand' in angular.

Arwin
  • 973
  • 1
  • 10
  • 21