Recursive Menus with AngularJS Templates

By on

AngularJS supports Templates and you can do a lot of great stuff with them. Recently I created a tree-like structure with an unknown depth. Templates are great to work with recursion.

Here is a simple controller::

function MenuCtrl ($scope, $http) {
   $scope.menuItems = [];

   $scope.loadMenu = function() {
      $http.get('menu/all').success(function(items) {
         $scope.menuItems = items;
      });
   };

   $scope.loadMenu();
}

This controller is supposed to load the whole menu at once. You can rewrite this to work with "ng-click". I want to keep this example simple, so I just loaded the whole tree at once.

A menuItem has children property which can contain menuItems.

Now let's create a template which calls itself:

<script type="text/ng-template" id="tree-renderer.html">
 <a href=""></a>
 <ul>
   <li ng-repeat="menuItem in menuItem.children" ng-include="'tree-renderer.html'></li>
 </ul>
</script>

As you can see the ng-include directive can get a string as parameter. Please mind the extra ' surrounding the template id in line 4 if you pass a string. You can reference the same template from inside the template.

The initial call would look almost exactly like the template:

<ul>
  <li ng-repeat="menuItem in menuItems" ng-include="'tree-renderer.html'"></li>
</ul>

The output is a nested tree of lists.

The good thing with this approach is you benefit from two-way-data-binding. If you update your model your view is updated too. That way you can build up a very powerful menu builder like I did.

Surprisingly easy, as I found afterwards.

Tags: AngularJS, JavaScript, Open Source