angularjs directive set template url dynamically
26,740
Solution 1
You can pass a function to the templateUrl option and return a string that will be used as a template url at the end.
First of all assign a role onto the element as an attribute (where userRole is bound to scope) as:
<div my-directive user-role="{{userRole}}></div>
Then the directive can read it as:
myApp.directive('myDirective', function() {
return {
restrict: 'A',
templateUrl: function(element, attrs) {
return "../assets/common/headerMenu" + attrs.userRole + ".html";
}
}
});
Update: This used to work before with older version of Angular.
<div ng-if="userRole === 'admin'" my-directive user-role="admin"></div>
Solution 2
you can manipulate ng-include
as a template
html:
<headermenu user-role="selectedUserRole"></headermenu>
js:
app.directive('headermenu', function() {
return {
restrict: 'E',
scope: {
userRole : '='
},
link: function($scope)
{
$scope.$watch('userRole', function(userRole)
{
if (userRole && userRole.length)
{
$scope.dynamicTemplateUrl = 'assets/common/headerMenu' + userRole + '.html';
}
});
},
template: '<ng-include src="dynamicTemplateUrl"></ng-include>'
};
});
demo: http://plnkr.co/edit/CCElZ317kYeZpa5ofmoo?p=preview
Or if you don't want to set the full path in the controller:
html:
<headermenu path="assets/common/headerMenu{{selectedUserRole}}.html"></headermenu>
js:
app.directive('headermenu', function() {
return {
restrict: 'E',
scope: {
path : '@'
},
template: '<ng-include src="path"></ng-include>'
};
});
demo: http://plnkr.co/edit/HEyUUzv6jbjZCDDbAzPm?p=preview
Solution 3
Why not do:
template : '<div ng-include="getActualTemplateContent()"></div>'
then:
$scope.getActualTemplateContent= function() {
return '../assets/common/headerMenu/' + $scope.user_role + '.html';
};
Solution 4
If not put it in the markup.
<div headermenu template="../assets/common/headerMenu{{user_role}}.html" />
<headermenu template="../assets/common/headerMenu{{user_role}}.html" />
angular.module("directives")
.directive("headermenu", function() {
return {
restrict: "EA",
scope: true,
templateUrl: function (element, attr) {
return attr.template;
},
link: function(scope, iElement, iAttrs, controller) {
....
}
};
});
![Sachin Prasad](https://i.stack.imgur.com/vcVX6.jpg?s=256&g=1)
Comments
-
Sachin Prasad over 3 years
I'm creating a directive with template URL. I want to set the template URL dynamically based on user_role. Any idea?
Heres my directive code:
RatingRX.directive "headermenu", -> directive = {} directive.restrict = 'E' directive.templateUrl = "../assets/common/headerMenu{{user_role}}.html" directive
And I want to set user_role from the controller. Eg:
$scope.user_role = 1
-
Sachin Prasad over 9 yearsWell if theres no other way I'll have to follow this, but Again I'll have to set the full path in the controller.
-
Ben Heymink over 9 yearsWhat do you mean you'll 'have to set the full path in the controller'? How else were you expecting to tell Angular which template file to use?
-
Sachin Prasad over 9 yearsWhen I use this: directive.templateUrl, I'll have to set the full path of the template only once and in the controller I'll simply pass the user role, and it will pick it dynamically, based on that user role.
-
Ben Heymink over 9 yearsSorry I must be missing something - the snippet I've given you does exactly what you want I think - it will load a template based on the user role provided to $scope.user_role, dynamically. If there is some other requirement you have, you need to update your question with a bit more explanation?
-
RMD about 9 yearsThis doesn't actually work; the attrs.userRole is passed in the "{{userRole}}" string directly, and not the actual value.
-
Nitesh Kumar Anand over 8 yearsThis will not work because scope is not evaluated yet and is not available too.
-
mariomol about 8 yearsthe first one is the best answer.. but i used rootscope to watch a variable that refresh the dynamic template url with the object
-
Mad over 7 yearsDid u try this before you put it as the answer, I am pretty sure this won't work with binded values.
-
codef0rmer over 7 years@Mad As I mentioned in the updates, the interpolation will not work in the latest angular but it was working back then (answered Oct 16th 2014).