2013-04-22 79 views
10

我試圖根據當前項目動態顯示ng-repeat指令中的幾個模板之一。在AngularJS中動態顯示ng-repeat指令中的模板?

我的JSON數據是這樣的:

data: { 
    groups: [ 
     { 
      name: "Group 1",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     }, 
     { 
      name: "Group 2",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     } 
    ] 
} 

我的目標是動態地呈現數據的樹,包含多個部分,每組。這些組將具有相同的模板,但每個部分都應該有自己的模板,基於名稱字段。

假設頂層HTML是:

<div ng-repeat="group in groups"> 
    {{ group.name }} 
    <div ng-repeat="section in sections"> 
     <!-- Dynamic section template used --> 
    </div> 
</div> 

理想的情況下,每一部分也需要有自己的作用域的數據和與之相關的控制器。我用Knockout構建這種類型的系統已經有了很好的運氣,但我試圖理解Angular的做事方式。

+0

聽起來就像一個指令的好例子。 – lucuma 2013-04-22 19:56:34

+0

Lucuma,你能評論更多嗎?我也想過使用指令,但我不確定理想的粒度級別。我應該建立一個指令,只是選擇模板,還是每個「部分」都有自己的指令? – 2013-04-23 12:17:55

+0

我認爲這取決於你想怎麼做。您可以創建一個指令來完成所有操作(傳入組數組),並且/或者您可以創建另一個在您的groups指令中調用的指令來處理這些部分。指令的好處是他們有自己的範圍。我將提供一個小例子。 – lucuma 2013-04-23 13:19:44

回答

31

你可以做這樣的事情:

<div ng-repeat="group in groups"> 
    {{ group.name }} 
    <div ng-repeat="section in sections" ng-include="getIncludeFile(section)"> 
     <!-- Dynamic section template used --> 
    </div> 
</div> 

然後在你的控制器:

$scope.getIncludeFile = function(section) { 
    // Make this more dynamic, but you get the idea 
    switch (section) { 
     case "Section A": 
      return 'partials/sectiona.html'; 
     case "Section B": 
      return 'partials/sectionb.html'; 
    } 
} 

然後你sectiona.html看起來是這樣的(具有特定該文件控制器):

<div ng-controller="SectionAController"> 
    <!-- HTML in here, and can bind straight to your SectionAController --> 
</div> 
+0

這是我現在最直接的使用方法。如果我的需求變得更加複雜,我可能會採用指令方法。 – 2013-04-29 19:53:58

+0

工程就像一個魅力,優秀的解決方案! – chromaloop 2014-09-26 20:17:38

+0

如果我想將json項目轉換爲路由到新頁面的鏈接列表,該怎麼辦......所有這些頁面將遵循具有獨特屬性的相同模板,如後期類型....但我不需要數據庫或管理員。只需要爲具有相同視圖模板的每個數據項目創建一個新頁面。 – Omar 2017-01-12 18:07:56

4

在過去的一個月裏,爲了支持動態模板,但是我沒有找到關於它的使用的很多信息。這裏是參考。 https://github.com/angular/angular.js/pull/1849

雖然這仍然使用相同的nginclude這一切都是封裝在兩個指令:

演示:http://plnkr.co/edit/4DIlHMNlHQ8Wm9XHNycH?p=preview

HTML:

<groups-control groupdata="groups"></groups-control> 

控制器:

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    var json = {data: { 
    groups: [ 
     { 
      name: "Group 1",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     }, 
     { 
      name: "Group 2",     
      sections: [ 
       { name: "Section A" }, 
       { name: "Section B" } 
      ] 
     } 
    ] 
    }}; 
    $scope.groups = json.data.groups; 

}); 

指令拆分爲兩個:

app.directive('groupsControl', function(){ 
    return { 
     restrict: 'E', 

     replace: true, 
     transclude: false, 
     scope: { items:'=groupdata'}, 

     template: '<div ng-repeat="group in items">' + 
        '{{ group.name }}' + 
        '<section-control sections="group.sections" />'+ 

       '</div>', 
     // The linking function will add behavior to the template 
     link: function(scope, element, attrs) { 


     } 
    } 
    }).directive('sectionControl', function(){ 
    return { 
     restrict: 'E', 

     replace: true, 
     transclude: false, 
     scope: { items:'=sections'}, 

     template: '<div ng-repeat="section in items" ng-include="getIncludeFile(section)">'+ 
       '</div>', 

     link: function(scope, element, attrs) { 
     scope.getIncludeFile = function(section) { 
      return section.name.toLowerCase().replace('section ','') + ".html"; 
     } 

     } 
    } 
    }); 

我真的想看到有人發表一個基於某些範圍數據使用templateUrl函數的答案。