Last Updated: September 09, 2019
·
58.71K
· gerardsans

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

AngularJs Meetup South London Collection | this article

8 Responses
Add your response

Thanks for this great tutorial! I was looking for exactly this feature. Many many thanks.
Best regards
Wim

over 1 year ago ·

Why not using ngSwitch?

over 1 year ago ·

You could use ngSwitch too but it wouldn't be a dynamic template then.

over 1 year ago ·

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

over 1 year ago ·

It seems is browser related as shows DOM manipulation. Is pointing to attributes. Maybe it doesn't like data-content attribute?

over 1 year ago ·

I didn't understand your point. What do I have to change?

over 1 year ago ·

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.

over 1 year ago ·

OK gsans, I'll make other tests. Thank you for your help.

over 1 year ago ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip
Did you know?

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