Recursive custom directives using ngRepeat
angularjs, angularjs-directive, angularjs-ng-repeat
Solution
The problem is that you're trying to define your directive recursively, when angular was trying to compile the template, it saw `treeview` directive, it called `treeview`'s compile function, then it saw `treeviewItem` directive, it called `treeviewItem`'s compile function, then it saw `treeviewItem` directive, it called `treeviewItem`'s compile function,then it saw `treeviewItem` directive, it called `treeviewItem`'s compile function...
See the problem? The calls to compile functions couldn't stop. So, you need to pull the recursive definition out of your template, but use `$compile` to build DOM manually:
module.directive('treeviewItem', function ($compile) {
return {
restrict: 'E',
template: '<li><i class="icon-plus-sign"></i><a href="/"><i class="icon-folder-close"></i>{{item.text}}</a></li>',
replace: true,
scope: {
item: "="
},
link: function (scope, element, attrs) {
element.append($compile('<ul><treeview-item ng-repeat="childitem in item.childitems" item="childitem"></treeview-item></ul>')(scope));
console.log("treeview item directive loaded");
}
};
});
http://jsfiddle.net/SKPpv/3/
Alternatively, I found a solution to display tree-like data on SO https://stackoverflow.com/a/11861030/69172. The solution however uses `ngInclude` instead of directives.
Problem
I'm trying to create a treeview using AngularJS. Here's my code: ``` module.directive('treeview', function () { return { restrict: 'E', templateUrl: "/templates/ui/controls/treeview.htm", replace: true, transclude: true, scope: {}, link: function (scope, element, attrs) { console.log("treeview directive loaded"); }, controller: function ($scope, $rootScope) { $rootScope.depth = 0; $scope.items = [ { text: "face" }, { text: "palm" }, { text: "cake", childitems: [ { text: "1 face" }, { text: "1 palm" }, { text: "1 cake" } ] } ]; } }; }); module.directive('treeviewItem', function () { return { restrict: 'E', templateUrl: "/templates/ui/controls/treeview-item.htm", replace: true, scope: { item: "=" }, link: function (scope, element, attrs) { console.log("treeview item directive loaded"); } }; }); ``` Treeview template: ``` <div class="sl-treeview"> <ul class="clear" ng-transclude> <treeview-item ng-repeat="item in items" item="item"></treeview-item> </ul> </div> ``` Treeview Item template: ``` <li> <i class="icon-plus-sign"></i> <a href="/"> <i class="icon-folder-close"></i> {{item.text}} </a> <!-- This ul is the issue - it crashes the page --> <ul> <treeview-item ng-repeat="childitem in item.childitems" item="childitem"></treeview-item> </ul> </li> ``` In the treeview directive `$scope.items` is hardcoded for development - eventually I hope this will come from a controller/service pulling data from the server. However it represents the sort of basic structure I'm looking for. When I run this without the nested ul in treeviewItem it gives me the first three items just fine. When i add the ul in to try and get the controls to bind with child items it hands the page and stops working. JSFiddle without nested ul - working: http://jsfiddle.net/BdmV3/ JSFiddle with nested ul - not working (and may hang your browser!): http://jsfiddle.net/SKPpv/ How should I go about making a control that uses a custom directive and ngRepeat to create potentially infinite levels of recursion? Why isn't my approach working?