AngularJS directive dynamic templates
Solution 1
1) You are passing content as attribute in your html. Try this:
element.html(getTemplate(attrs.content)).show();
instead of:
element.html(getTemplate(scope.content)).show();
2) data part of directive is getting compiled so you should use something else. Instead of data-type, e.g. datan-type.
Here is the link:
http://jsbin.com/mibeyotu/6/edit
Solution 2
You can set the template
property of your directive definition object to a function that will return your dynamic template:
restrict: "E",
replace: true,
template: function(tElement, tAttrs) {
return getTemplate(tAttrs.content);
}
Notice that you don't have access to scope at this point, but you can access the attributes through tAttrs
.
Now your template is being determined before the compile phase, and you don't need to manually compile it.
Solution 3
You can also do it very straightforward like this:
appDirectives.directive('contextualMenu', function($state) {
return {
restrict: 'E',
replace: true,
templateUrl: function(){
var tpl = $state.current.name;
return '/app/templates/contextual-menu/'+tpl+'.html';
}
};
});
Solution 4
If you need to load your template based on $scope
variables you can do it 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';
}
}
}
};
});
Reference: https://coderwall.com/p/onjxng/angular-directives-using-a-dynamic-template
Jack
Updated on December 20, 2020Comments
-
Jack over 3 years
I'm trying to make directive with differtent templates based on scope value.
This is what i done so far which i don't know why doesn't work http://jsbin.com/mibeyotu/1/edit
HTML element:
<data-type content-attr="test1"></data-type>
Directive:
var app = angular.module('myApp', []); app.directive('dataType', function ($compile) { var testTemplate1 = '<h1>Test1</h1>'; var testTemplate2 = '<h1>Test2</h1>'; var testTemplate3 = '<h1>Test3</h1>'; var getTemplate = function(contentType){ var template = ''; switch(contentType){ case 'test1': template = testTemplate1; break; case 'test2': template = testTemplate2; break; case 'test3': template = testTemplate3; break; } return template; }; var linker = function(scope, element, attrs){ element.html(getTemplate(scope.content)).show(); $compile(element.contents())(scope); }; return { restrict: "E", replace: true, link: linker, scope: { content:'=' } }; });
-
Jack about 10 yearsJust one question, if i'm doing ng-repeat, for example: ng-repeat="p in people" i can't get value like this: content="p.name". Because this directive is inside ng-repeat cycle.
-
Val Redchenko almost 10 yearsPlease note that templateUrl can also be a function
-
sasklacz almost 10 yearsI'm getting errors when 'show' is called at the end. Work properly without it. Not sure if it's a legacy thing or what.
-
tftd over 8 yearsHow would you pass
$state
to the directive? -
DeBraid over 8 yearsBest answer if you're looking for simple method to control
template
based on the route. -
eloone over 8 years@tftd like this
(function(angular){ angular.module('myModule', ['ui.router']) .directive('myDirective', ['$state', function($state){ return { templateUrl: 'tpl.html' }; }]); })(window.angular);
-
Shikha thakur almost 8 yearshi, When i implemented the same code as yours i am getting error as angular.js:13708 Error: [$compile:tpload] Failed to load template: <ng-include src="getTemplateUrl()"/> (HTTP status: 404 Not Found) Could you please help me out with this
-
Karolis.sh almost 8 yearsCould you provide directive controller code? My guess is that directive's scope doesn't have the
getTemplateUrl
function and browser tries to loadundefined
template. -
Gary almost 8 years@Slaven Tomac I am trying to add form elements dynamically. But when adding items with ng-repeat and ng-options dynamically it does not show the repeat items. Just the static HTML. Here is what I mean to say. plnkr.co/edit/JOzTWB6tuyilCJ8Rj37Q Any issues with the code or can ng-repeat be also compiled in the template.
-
Nicu Surdu over 7 yearsThis doesn't work if your directive is using
transclude
, but nice approach anyway ;) -
Tiberiu C. about 7 yearswhen
templateUrl
is specified like a function that function receives two arguments, the first is the element and the second is the scope. So to get hold of the isolated scope is easier to use the one from the callback :{templateUrl : function($el, $scope) { return '..'+$scope.name+'..'}}
-
Danny Coulombe almost 7 years@Tiberiu C. The second argument is not the $scope, but the attributes.
-
Sotiris Zegiannis over 3 yearsthe tAttrs.content doesnt return the actual value of the content, just the hmtl template value.