Динамическое отображение шаблона в директиве 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 делать вещи.

Ответ 1

Вы можете сделать что-то вроде этого:

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

Ответ 2

В прошлом месяце была проверка на angular для поддержки динамических шаблонов в директиве, однако я не смог найти очень много информации относительно ее использования. Вот ссылка. 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 на основе некоторых данных области.