2013-08-11 2 views
9

Я пытаюсь создать древовидную структуру с помощью AngularJS.Рекурсивные пользовательские директивы, использующие ngRepeat

Вот мой код:

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:

<div class="sl-treeview"> 
    <ul class="clear" ng-transclude> 
     <treeview-item ng-repeat="item in items" item="item"></treeview-item> 
    </ul> 
</div> 

Treeview Пункт шаблон:

<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> 

В директиве TreeView $scope.items жестко закодирован для развития - в конце концов, я надеюсь, что это будет поступать из контроллера/услуги, извлекающего данные из р. Однако он представляет собой базовую структуру, которую я ищу.

Когда я запускаю это без вложенной ul в treeviewItem, он дает мне первые три элемента просто отлично. Когда я добавляю ul в, чтобы попытаться связать элементы управления с дочерними элементами, он передает страницу и перестает работать.

JSFiddle без вложенной ул - рабочий: - (! И может повиснуть ваш браузер)

http://jsfiddle.net/BdmV3/

JSFiddle с вложенными ул не работает:

http://jsfiddle.net/SKPpv/

Как я должен идти о создавая элемент управления, который использует настраиваемую директиву и ngRepeat для создания потенциально бесконечных уровней рекурсии? Почему мой подход не работает?

ответ

15

Проблема заключается в том, что вы пытаетесь определить свою директиву рекурсивна, когда Угловой пытаются составить шаблон, он увидел treeview директивы, она называется treeview «s компилировать функцию, то увидело treeviewItem директивы, она называется treeviewItem» s компилировать функции, то он увидел treeviewItem директивы, она называется treeviewItem «ы обобщит функцию, то он увидел treeviewItem директивы, она называется treeviewItem» s компилировать функции ...

Смотрите эту проблему? Вызовы для компиляции функций не могли прекратиться. Таким образом, вы должны вытащить рекурсивное определение из вашего шаблона, но использовать $compile построить DOM вручную:

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/

Кроме того, я нашел решение для отображения древовидных данных на SO https://stackoverflow.com/a/11861030/69172. Однако в решении вместо директив используется ngInclude.

+0

Я столкнулся с компиляцией $, глядя на другие примеры древовидных изображений, и это был вариант, который я взял. Он работает красиво. Чтобы вы объяснили, почему мой оригинальный подход не работает, это очевидно сейчас! Из интереса, почему вы смотрите 'item.childitems'? Разве это не добавит ul для каждого дочернего элемента? – Jon

+0

@Jon Я не должен использовать '$ watch', как это в моем первоначальном ответе, он просто добавит другую' ul' всякий раз, когда меняет «childitems». Я обновил свой ответ, не используя '$ watch'. Кроме того, можете ли вы поделиться примером дерева, который вы нашли в своем вопросе, чтобы каждый мог больше воспользоваться вашим вопросом? –

+0

Это больше не работает в новых версиях угловых (> 1.2) –

Смежные вопросы