I am attempting to dynamically display one of several templates within an ng-repeat directive, based on the current item.
My JSON data looks like this:
In the past month there was a checkin to angular for supporting dynamic templates in a directive however I wasn't able to find very much information with regards to its use. Here is the reference. https://github.com/angular/angular.js/pull/1849
Although this still uses the the same nginclude it is all encapsulated in two directives:
Demo: http://plnkr.co/edit/4DIlHMNlHQ8Wm9XHNycH?p=preview
HTML:
<groups-control groupdata="groups"></groups-control>
Controller:
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;
});
Directive split into two:
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";
}
}
}
});
I'd actually like to see someone post an answer using a function for the templateUrl based on some of the scope data.
You could do something like this:
<div ng-repeat="group in groups">
{{ group.name }}
<div ng-repeat="section in sections" ng-include="getIncludeFile(section)">
<!-- Dynamic section template used -->
</div>
</div>
Then in your controller:
$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';
}
}
Then your sectiona.html could look like this (to have a controller specific to that file):
<div ng-controller="SectionAController">
<!-- HTML in here, and can bind straight to your SectionAController -->
</div>