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.
Have a fresh tip? Share with Coderwall community!
Angular apps often share the page with analytics and payment scripts that are not Angular modules. Those scripts execute on the same origin as the framework.
Security insights from Cside