0

I am trying to build a recursive angular directive that will display a menu, but the browser stuck when it tries to render it, which probably because of infinite loop of rendering for some reason, but I can't figure out exactly how to solve it in an elegant way.

There are the two directives I am using:

  1. category-menu that loads the json content and creates inner directives of category-menu-item.
  2. category-menu-item represents a menu sub-item. This directive creates inner category-menu-item directives if the nodes array is not empty.

Example of the JSON data structure (one menu item contains another menu item):

[{
    "id": 1,
    "title": "Sample title",
    // array of inner nodes (with the same structure as this one)
    "nodes": [{
        "id": 2,
        "title": "inner title",
        "nodes": []
    }]
}]

here is the code of the two directives:

    app.directive('categoryMenu', ['$http', function($http) {
        return {
            restrict: 'E',
            templateUrl: 'app/templates/categoryMenu.html',
            link: function (scope, elem, attrs) {
                // set scope.nodes with some fake data. 
                // originally retreives the data using $http.get
                scope.nodes = [{
                    "id": 4,
                    "title": "title 4",
                    "nodes": [{
                        "id": 9,
                        "title": "title 9",
                        "nodes": [{
                            "id": 10,
                            "title": "title 10",
                            "nodes": [{
                                "id": 12,
                                "title": "title 12",
                                "nodes": []
                            }, {
                                "id": 13,
                                "title": "title 13",
                                "nodes": []
                            }]
                        }]
                    }]
                }];
            }
        }
    }])
        .directive('categoryMenuItem', [function() {
            return {
                restrict: 'E',
                scope:{
                    category: '='
                },
                templateUrl: 'app/templates/categoryMenuItem.html'
            }
        }]);

here is the template for category-menu directive:

<li class="dropdown">
    <a class="dropdown-toggle" href="#">
        Catalog
        <i class="fa fa-angle-down"></i>
    </a>
    <ul class="dropdown-menu" ng-if="nodes.length!=0">
        <category-menu-item ng-repeat="node in nodes" category="node"></category-menu-item>
    </ul>
</li>

here is the template for category-menu-item directive:

<li class="dropdown-submenu" ng-if="category.nodes.length!=0">
    <a href="#/categories/{{category.id}}">{{category.title}}</a>
    <ul class="dropdown-menu">
        <category-menu-item ng-repeat="node in category.nodes" category="node"></category-menu-item>
    </ul>
</li>
<li ng-if="category.nodes.length==0"><a href="#/categories/{{category.id}}">{{category.title}}</a></li>

Here is more complex data:

[{
    "id": 4,
    "title": "title 4",
    "nodes": [{
        "id": 9,
        "title": "title 9",
        "nodes": [{
            "id": 10,
            "title": "title 10",
            "nodes": [{
                "id": 12,
                "title": "title 12",
                "nodes": []
            }, {
                "id": 13,
                "title": "title 13",
                "nodes": []
            }]
        }]
    }]
}]

Thanks!

Aviran Cohen
  • 5,581
  • 4
  • 48
  • 75
  • category-menu-item inside category-menu-item will surely hit $digest TTL, but I am not sure ng-if check can prevent that. may be check in console for $digest loop error? – YOU Apr 11 '15 at 16:11
  • this [one](http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/) using replace:true, but it is deprecated, but you can try. – YOU Apr 11 '15 at 16:15
  • I removed replace:true on its [jsbin](http://jsbin.com/hukevixuwa/3/edit), its still works, may be you just need to $compile yourself on link function. – YOU Apr 11 '15 at 16:20
  • There's an excellent solution here: http://stackoverflow.com/questions/14430655/recursion-in-angular-directives – Yaron Schwimmer Apr 13 '15 at 11:03

0 Answers0