Angular - Directives: using a dynamic template
AngularJs Meetup South London Collection | this article
Directives are a very powerful concept in Angular. Let's say we want to create a directive to display user profiles. The final directive should be used like this
<profile data="{name:'John', type='twitter'}"/>
<profile data="{name:'Maria', type='facebook'}"/>
Internally we want the directive to change the template being used based on the user type. In order to setup a template for your directive you can use template or templateUrl options.
This would be the initial version
Profile directive (using template)
.directive("profile", function() {
return {
template: '<h1 ng-bind="user.name"></h1>',
scope: {
user: '=data'
},
restrict: 'E'
};
});
This works fine but still does not take into account the type. We can move the template to a file first and use templateUrl.
Profile directive (using templateUrl)
.directive("profile", function() {
return {
templateUrl: 'profile.tpl.html',
scope: {
user: '=data'
},
restrict: 'E'
};
});
In order to implement the dynamic template we can't use any of the two so we have to resort to another approach using ng-include. We can't use templateUrl as it has no access to $scope.user.type.
templateUrl: function() { return "profile.tpl.html";} //no access to $scope
Dynamic template using ng-include
.directive("profile", function() {
return {
template: '<ng-include src="getTemplateUrl()"/>',
scope: {
user: '=data'
},
restrict: 'E',
controller: function($scope) {
//function used on the ng-include to resolve the template
$scope.getTemplateUrl = function() {
//basic handling
if ($scope.user.type == "twitter")
return "twitter.tpl.html";
if ($scope.user.type == "facebook")
return "facebook.tpl.html";
}
}
};
});
Demo code: link
Written by gerardsans
Related protips
8 Responses
Thanks for this great tutorial! I was looking for exactly this feature. Many many thanks.
Best regards
Wim
Why not using ngSwitch?
You could use ngSwitch too but it wouldn't be a dynamic template then.
Hi, and thanks for the post.
I used your code to get dynamic template but I am getting an error despite the code is working.
Do you know what it is?
Error:
At Chrome = TypeError: undefined is not a function at forEach.attr
At Firefox = Error: element.setAttribute is not a function
You can see more datails on: http://stackoverflow.com/questions/30668661/angular-directive-with-dynamic-template
It seems is browser related as shows DOM manipulation. Is pointing to attributes. Maybe it doesn't like data-content attribute?
I didn't understand your point. What do I have to change?
I created a little test and it worked fine for me. I believe your issue is in your data and not in the approach shown here.
OK gsans, I'll make other tests. Thank you for your help.