49

I've got a recursive Angular directive that uses a template variable and gets compiled in the link function.

Problem is, that my template has gotten really long and out of control and I want to externalize it in an external HTML file (it would also make it easier for example to auto-indent).

How can you load an external template into a directive that can be used inside the $compile?

I've seen templateURL, but that doesn't let me name the variable and pass it to the $compile function.

var template = 
           "<p>My template</p>"+
           "<this-directive val='pass-value'></this-directive>";

return {
     scope: {
     ...
     },
     ...
     link: function(scope, element){
            element.html(template);
            $compile(element.contents())(scope);
        }
}

and

2 Answers 2

109

You can use the $templateRequest service to get the template. This is a convenience service that also caches the template in $templateCache, so that only a single request to template.html is made.

As an illustration (and without going into the issue of recursive directives), this is used like so:

link: function(scope, element){
   $templateRequest("template.html").then(function(html){
      var template = angular.element(html);
      element.append(template);
      $compile(template)(scope);
   });
};

plunker (check the network tab to see a single network request)

Sign up to request clarification or add additional context in comments.

5 Comments

This is awesome! You are my hero! Can I buy you a coffee?
I'm curious, is it possible to use html binding (ng-bind-html) inside the "template.html" in your illustration? I can't make it work.
@zhekaus, yes, but it you still need to use the usual ngSanitize/$sanitize or otherwise use $sce.trustAsHtml
Do you know why this appears to uncompile whenever it is converted to a string or console logged?
Just curious is there is a way to maintain two way binding for the template.html
3

I prefer to use $http to load template if its size is bigger:-

$http.get('mytemp.html').then(function(response) {
            element.html(response.data);
            $compile(element.contents())(scope);
            });

3 Comments

You should cache the templates that you load, like this $http.get('mytem.html', {cache: $templateCache}).then(function(response) { element.html(response.data); $compile(element.contents())(scope); })
There is a missing parenthesis in the code but I can't edit because it's less than 6 chars :)
"The $templateRequest service runs security checks then downloads the provided template using $http and, upon success, stores the contents inside of $templateCache." AngularJS So $templateCache uses $http performing additional operations in one line. The only difference I see is that the template is not put into $templateCache, was it the purpose of your code?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.