Using $compile on external template (templateURL) in Angular directive

38,576

Solution 1

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)

Solution 2

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);
            });
Share:
38,576
CodyBugstein
Author by

CodyBugstein

Aspiring computer nerd.

Updated on July 23, 2020

Comments

  • CodyBugstein
    CodyBugstein almost 4 years

    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

  • CodyBugstein
    CodyBugstein over 9 years
    This is awesome! You are my hero! Can I buy you a coffee?
  • Leonardo
    Leonardo about 9 years
    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); })
  • Leonardo
    Leonardo about 9 years
    There is a missing parenthesis in the code but I can't edit because it's less than 6 chars :)
  • felix at housecat
    felix at housecat over 8 years
    "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?
  • zhekaus
    zhekaus over 8 years
    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.
  • New Dev
    New Dev over 8 years
    @zhekaus, yes, but it you still need to use the usual ngSanitize/$sanitize or otherwise use $sce.trustAsHtml
  • A Star
    A Star almost 8 years
    Do you know why this appears to uncompile whenever it is converted to a string or console logged?
  • AshD
    AshD about 6 years
    Just curious is there is a way to maintain two way binding for the template.html