Can you change templateUrl on the fly?

It is possible, but when your template to be loaded depends on some scope-data you can’t use the directive’s templateUrl property anymore and you will be obliged to use lower-level API, namely $http and $compile.

Roughly what you need to do (only possible in the linking function) is to retrieve template’s content using $http (don’t forget to involve $templateCache!) and then compile template’s content “manually”.

It might sound like it is a lot of work but in practice it is rather straightforward. I would suggest having a look at the ngInclude directive sources where this pattern is used.

Here is a skeleton of such a directive:

app.directive('boom', function($http, $templateCache, $compile, $parse) {
        return {
            restrict: 'E',
            link: function(scope , iElement, iAttrs) {                            
              var boom = $parse(iAttrs.data)(scope);
              $http.get('myTemplate'+boom, {cache: $templateCache}).success(function(tplContent){
                iElement.replaceWith($compile(tplContent)(scope));                
              });              
            } 
        }
    });

assuming that it would be used as <boom data="name"></boom>. Working plunk here: http://plnkr.co/edit/TunwvhPPS6MdiJxpNBg8?p=preview

Please note that I’ve changed attributes evaluation from {{name}} to attributes parsing since probably a template should be determined only once, at the beginning.

Leave a Comment