2013-08-11 43 views
9

Tôi đang cố gắng tạo một chế độ xem ảnh bằng AngularJS.Chỉ thị tùy chỉnh đệ quy sử dụng ngRepeat

Dưới đây là mã của tôi:

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 mẫu:

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

Treeview hàng mẫu:

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

Trong chỉ thị treeview $scope.items là hardcoded cho sự phát triển - cuối cùng tôi hy vọng điều này sẽ đến từ một bộ điều khiển/dịch vụ lấy dữ liệu từ dịch vụ r. Tuy nhiên nó đại diện cho loại cấu trúc cơ bản mà tôi đang tìm kiếm.

Khi tôi chạy điều này mà không có nested lồng nhau trong treeviewItem nó mang lại cho tôi ba mục đầu tiên tốt. Khi tôi thêm ul vào để thử và có được các điều khiển để ràng buộc với các mục con nó tay trang và ngừng làm việc.

JSFiddle mà không ul lồng nhau - làm việc: - (! Và có thể treo trình duyệt của bạn)

http://jsfiddle.net/BdmV3/

JSFiddle với ul lồng nhau không làm việc:

http://jsfiddle.net/SKPpv/

Làm thế nào tôi nên đi về tạo một điều khiển sử dụng một chỉ thị tùy chỉnh và ngRepeat để tạo ra các mức đệ quy vô hạn? Tại sao phương pháp tiếp cận của tôi không hoạt động?

Trả lời

15

Vấn đề là bạn đang cố gắng để xác định chỉ thị của bạn một cách đệ quy, khi góc đã cố gắng để biên dịch mẫu, nó thấy treeview chỉ thị, nó được gọi là treeview 's biên dịch chức năng, sau đó nó thấy treeviewItem chỉ thị, nó được gọi là treeviewItem' s biên dịch chức năng, sau đó nó thấy treeviewItem chỉ thị, nó được gọi là treeviewItem 's biên dịch chức năng, sau đó nó thấy treeviewItem chỉ thị, nó được gọi là treeviewItem' s biên dịch chức năng ...

Xem vấn đề? Các cuộc gọi để biên dịch các chức năng không thể dừng lại. Vì vậy, bạn cần phải kéo các định nghĩa đệ quy ra của mẫu của bạn, nhưng sử dụng $compile để xây dựng DOM bằng tay:

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/

Ngoài ra, tôi tìm thấy một giải pháp để hiển thị dữ liệu cây như trên SO https://stackoverflow.com/a/11861030/69172. Tuy nhiên, giải pháp sử dụng ngInclude thay vì chỉ thị.

+0

Tôi bắt gặp biên dịch $ xem các ví dụ khác về số lần xem tre và đó là tùy chọn tôi đã thực hiện. Nó hoạt động rất đẹp. Rằng bạn cho lời giải thích lý do tại sao phương pháp tiếp cận ban đầu của tôi không hoạt động, nó hiển nhiên bây giờ! Không quan tâm, tại sao bạn lại xem 'item.childitems'? Sẽ không thêm một ul cho mỗi mục con? – Jon

+0

@ Jon Tôi không nên sử dụng '$ watch' như vậy trong câu trả lời ban đầu của tôi, nó sẽ đơn giản nối thêm một' '' bất cứ khi nào 'childitems' thay đổi. Tôi đã cập nhật câu trả lời của mình mà không sử dụng '$ watch'. Ngoài ra, bạn có thể chia sẻ ví dụ về treeview mà bạn đã tìm thấy trong câu hỏi của mình để mọi người có thể hưởng lợi nhiều hơn từ câu hỏi của bạn không? –

+0

Điều này không còn hoạt động trong các phiên bản mới hơn của góc (> 1.2) –

Các vấn đề liên quan