AngularJS directive dynamic templates

AngularjsAngularjs DirectiveAngularjs Scope

Angularjs Problem Overview


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:'='
        }
    };
});

Angularjs Solutions


Solution 1 - Angularjs

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 2 - Angularjs

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 3 - Angularjs

  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 4 - Angularjs

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJackView Question on Stackoverflow
Solution 1 - AngularjsDRiFTyView Answer on Stackoverflow
Solution 2 - AngularjselooneView Answer on Stackoverflow
Solution 3 - AngularjsSlaven TomacView Answer on Stackoverflow
Solution 4 - AngularjsKarolis Ĺ arapnickisView Answer on Stackoverflow