2013-04-22 11 views
10

Próbuję dynamicznie wyświetlać jeden z kilku szablonów w dyrektywie ng-repeat, na podstawie bieżącego elementu.Dynamicznie wyświetlając szablon w dyrektywie ng-repeat w AngularJS?

Moje dane JSON wygląda następująco:

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

Moim celem jest uczynienie drzewo danych dynamicznie, przy czym każda grupa zawiera wiele sekcji. Grupy będą miały ten sam szablon, ale każda sekcja powinna mieć własny szablon oparty na polu nazwy.

Zakładając najwyższym poziomie HTML jest:

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

Idealnie, każdy odcinek będzie również mieć swoje własne dane i lunetą kontroler z nim związane. Mam szczęście budowania tego typu systemu z Knockout, ale staram się zrozumieć Angularny sposób robienia rzeczy.

+0

Brzmi jak dobry przypadek dla dyrektywy. – lucuma

+0

Lucuma, czy mógłbyś skomentować więcej? Myślałem także o używaniu dyrektyw, ale nie jestem pewien idealnego poziomu szczegółowości. Czy powinienem zbudować dyrektywę, która dokonuje selekcji szablonów, czy też każda "sekcja" powinna mieć własną dyrektywę? –

+0

Myślę, że to zależy od tego, jak chcesz to zrobić. Możesz stworzyć jedną dyrektywę, aby wykonać to wszystko (przekazać w tablicy grup) i/lub możesz stworzyć kolejną dyrektywę, która jest wywoływana wewnątrz twojej dyrektywy grupowej, aby obsługiwać sekcje. Korzyścią dyrektywy jest to, że mają swój własny zakres. Podam mały przykład. – lucuma

Odpowiedz

31

Można zrobić coś takiego:

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

Następnie w kontrolerze:

$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'; 
    } 
} 

Wtedy twój sectiona.html mógłby wyglądać następująco (mieć kontroler specyficzne dla tego pliku):

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

To jest najprostsza metoda dla moich zastosowań już teraz. Jeśli moje potrzeby staną się bardziej skomplikowane, mogę zastosować podejście dyrektywy. –

+0

Działa jak urok, doskonałe rozwiązanie! – chromaloop

+0

co, jeśli chciałbym zmienić elementy json na listę linków, które prowadziłyby do nowej strony ...Wszystkie te strony byłyby zgodne z tym samym szablonem z unikalnymi właściwościami, takimi jak typ postu .... Ale nie potrzebuję bazy danych ani administratora. Wystarczy nowa strona dla każdego elementu danych z tym samym szablonem widoku. – Omar

4

W poprzednim miesiącu dokonano sprawdzenia pod kątem kątowym w celu obsługi dynamicznych szablonów w dyrektywy jednak nie byłem w stanie znaleźć bardzo wielu informacji dotyczących jego wykorzystania. Oto referencja. https://github.com/angular/angular.js/pull/1849

Mimo to nadal korzysta z tego samego nginclude to wszystko jest zamknięty w dwóch dyrektyw:

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

HTML:

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

Kontroler:

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; 

}); 

Dyrektywa podzielona na dwie części:

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"; 
     } 

     } 
    } 
    }); 

Chciałbym zobaczyć, jak ktoś wysyła odpowiedź za pomocą funkcji dla szablonuUrl na podstawie niektórych danych zakresu.

Powiązane problemy