0

I'm having trouble with a nested list Directive using Angular. Each time I try to run my code the browser crashes when I call the directive recursively.

I'd like to output a new list item if the children property in the data has items in it.

Here's a fiddle to my code, I removed the directives call to itself so that it does not crash the browser. http://jsfiddle.net/8p3bf4ec/

JS:

var jsonData = {
    "title": "Home",
    "author": "Mary",
    "children": [
        {
            "title": "Clothing",
            "author": "Robert",
            "children": [
                {
                    "title": "Shirts",
                    "author": "Bill",
                    "children": []
                }
            ]
        },
        {
            "name": "Electronics",
            "author": "William",
            "children": []
        }
    ]
};

angular.module('myApp', []);

angular.module('myApp').directive('itemList', function() {
    return {
        scope: true,
        templateUrl: 'itemListTemplate.html',
        controller: function($scope) {
            $scope.nodes = jsonData;
            console.log($scope.nodes);
        }
    };
});

Template:

<div ng-app="myApp">

    <item-list></item-list>

    <script type="text/ng-template" id="itemListTemplate.html">
        <ul>
            <li ng-repeat="node in nodes">
                {{node.title}}
            </li>
        </ul>
        <!-- Removed this because it makes the browser crash
        <item-list></item-list>
        -->
    </script>

</div>
5
  • Usng ng-repeat="node in nodes", the root of your jsonData should probably be an array -- var jsonData = [ { ... } ]; Otherwise, it's iterating the root object's values -- "Home", "Mary", etc. Commented Mar 23, 2015 at 14:00
  • render your directive element on some condition <item-list ng-ig="expression"></item-list> , as your calling it inside your template recursively..and directive is compiling infinite times..that's why browser is getting hanged.. Commented Mar 23, 2015 at 14:03
  • @JonathanLonowski I'd like it to be an array at the root but it's not and unfortunately it's not something I have control over. Commented Mar 23, 2015 at 14:37
  • @Mdd The directive could itself wrap the data in an Array -- $scope.nodes = angular.isArray(jsonData) ? jsonData : [ jsonData ]; Commented Mar 23, 2015 at 14:39
  • @JonathanLonowski Thanks, I had not realize that. I'm just starting out with Angular and directives are still pretty new to me but it seems like a good way to re-make a reuseable list. Commented Mar 23, 2015 at 14:43

1 Answer 1

1

It is because you infinitely iterate through jsonData instead of each node's children. I guess you should not use directive here at all because there is not much logic and it adds unnecessary complexity. Just use ng-include instead of directive. Something like this:

<script type="text/ng-template" id="tree-view">
<ul>
    <li ng-repeat="item in items">
        <!-- any data you want to display from item itself -->
        <div
            ng-if="item.children && item.children.length"
            ng-init="items=item.children"
            ng-include="'tree-view'">
        </div>
    </li>
</ul>
</script>

<div class="tree-view" ng-include="'tree-view'"></div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.