templateURL in directives

13,576 views
Skip to first unread message

Robert B. Weeks

unread,
Apr 11, 2012, 6:57:49 AM4/11/12
to ang...@googlegroups.com
Hello -

I was curious on the 'templateURL' field when creating a directive. What is this path relative to? I have had a hard time getting it to read in a file as the replacement for the template, and have tried multiple paths to do so.

That is what this field is for - correct? It looks that way according to the docs.

Thanks.

--
Robert B. Weeks


Robert B. Weeks

unread,
Apr 11, 2012, 11:38:21 AM4/11/12
to ang...@googlegroups.com
Hello -

Just to follow up on this question -

Is this what the 'templateURL' is used for?

In the docs it says "Same as template but the template is loaded from the specified URL" - I have been trying to get this to work as well.

So if I had a config for something like:

return {
restrict: 'E',
replace: true,
scope: {
myName: 'attribute'
},
templateURL: '/path/to/my/file.html',
link: function(scope, iElement, iAttrs, controller) {...}
};

Does 'templateURL' only take an id from an inlined template? Should we try to mimic what ng-include does in our own directives if we need to load the templates from the outside?

Thanks for any info.

Misko Hevery

unread,
Apr 11, 2012, 12:05:50 PM4/11/12
to ang...@googlegroups.com
should be just normal xhr url. can you open up a debugger in your browser and see what xhr url are you generating?

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.


Igor Minar

unread,
Apr 11, 2012, 12:33:51 PM4/11/12
to ang...@googlegroups.com
It will check the cache for inlined templates and if one is not found it will make an xhr to the url to fetch the template.

the url with "/" prefix is relative to the domain, without the "/" prefix it will be relative to the main ("index.html") page or base url (if you use location in the html5 mode).

/i

On Wed, Apr 11, 2012 at 8:38 AM, Robert B. Weeks <vai...@mac.com> wrote:

Robert B. Weeks

unread,
Apr 11, 2012, 1:50:59 PM4/11/12
to ang...@googlegroups.com
Hey -

That is what I figured as well, but I am not seeing that happen.

I can't figure out how to mimic really in a fiddle, but to show what I am seeing - this path works fine:

<ng-include src="'/resources/templates/replacement.html'"></ng-include>

but using same path in a directive is not giving what I am expecting. I have checked the network/xhr consoles as usual - but never see it try to grab it

With the call:

<current-dataset>Testing the current-dataset for {{serverName}}</current-dataset>

This works fine - with 'template' defined:

var appDirectives = angular.module('app.directives', []);
appDirectives.directive('currentDataset', function () {


return {
restrict: 'E',
replace: true,

transclude: true,
template: '<div>Replacement Content</div>'
}
});

But if I have that same template in the file listed in the ng-include above:

appDirectives.directive('currentDataset', function () {


return {
restrict: 'E',
replace: true,

transclude: true,
templateURL: '/resources/templates/replacement.html'
}
});

I get nothing, nor do I see any attempt to grab it via xhr in the consoles. Am I doing something wrong in the call above? I have tried wrapping it in '"xxx"' and "'xxx'". Do I need to do something special in the compile or link function?

Thanks - sorry I can't get to work in a fiddle - not sure how I would show that there.

Igor Minar

unread,
Apr 11, 2012, 1:57:26 PM4/11/12
to ang...@googlegroups.com
It's templateUrl not templateURL

/i

Robert B. Weeks

unread,
Apr 11, 2012, 2:19:14 PM4/11/12
to ang...@googlegroups.com
Hey -

Hmm - ok - the docs say it both ways -the example element does say that - sorry 'bout that - but the description shows it the other, that is where my confusion came from:

"templateURL - Same as template but the template is loaded from the specified URL. Because the template loading is asynchronous the compilation/linking is suspended until the template is loaded."

It does work with it like below (sigh). Thanks for the pointer.

One thing I did note though, is if the included html file begins with a comment (like to describe what it is), it will not load either.

Thanks for the reply. This helped a ton.

Igor Minar

unread,
Apr 11, 2012, 2:22:11 PM4/11/12
to ang...@googlegroups.com
oops. typo in the docs. I'll fix it.

/i

D. Zen

unread,
Apr 11, 2012, 3:59:14 PM4/11/12
to ang...@googlegroups.com
I was trying for awhile to use templateUrl without running a server. Is there a programmatic way to set the base url to the current directory?


On Wednesday, April 11, 2012 12:33:51 PM UTC-4, Igor Minar wrote:
It will check the cache for inlined templates and if one is not found it will make an xhr to the url to fetch the template.

the url with "/" prefix is relative to the domain, without the "/" prefix it will be relative to the main ("index.html") page or base url (if you use location in the html5 mode).

/i

On Wed, Apr 11, 2012 at 8:38 AM, Robert B. Weeks wrote:
Hello -

Just to follow up on this question -

Is this what the 'templateURL' is used for?

In the docs it says "Same as template but the template is loaded from the specified URL" - I have been trying to get this to work as well.

So if I had a config for something like:

  return {
      restrict: 'E',
      replace: true,
      scope: {
          myName: 'attribute'
      },
      templateURL: '/path/to/my/file.html',
      link: function(scope, iElement, iAttrs, controller) {...}
  };

Does 'templateURL' only take an id from an inlined template? Should we try to mimic what ng-include does in our own directives if we need to load the templates from the outside?

Thanks for any info.


> I was curious on the 'templateURL' field when creating a directive. What is this path relative to? I have had a hard time getting it to read in a file as the replacement for the template, and have tried multiple paths to do so.
>
> That is what this field is for - correct? It looks that way according to the docs.
>
> Thanks.
>

--
Robert B. Weeks




--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+unsubscribe@googlegroups.com.

Vojta Jína

unread,
Apr 11, 2012, 5:25:34 PM4/11/12
to ang...@googlegroups.com
I think running a simple node server is very simple, so I would recommend that.

Or just start chrome with flag --allow-file-access-from-files
To view this discussion on the web visit https://groups.google.com/d/msg/angular/-/8ZM8QAsx0jAJ.

To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.

Nash

unread,
Nov 30, 2012, 11:00:40 AM11/30/12
to ang...@googlegroups.com, vai...@mac.com
I started with the exact same issue as Robert - can't make the switch from inline template definition to templateUrl.  template:[...] works just fine, but templateUrl with the same html now gets me the following error, 
Error: Template must have exactly one root element. was: <html lang="en">

I've been messing with the DOM structure in the index file and the partial template file thinking that's the issue, but I'm not having much luck.  The only suggestion I've found so far is removing 'replace:true', however, this just results in an infinite rendering loop that blows up Chrome eventually.  What am I missing here?

Index.html,
<html lang="en">
<head>[...]</head>
<body ng-app="myApp">
    <my-elm></my-elm>
</body>
</html>

app.js
var myApp = angular.module('myApp', []);

directives.js, 
myApp.directive('myElm', function(){
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    templateUrl: 'partials/myElm.html'
  }
});

partials/myElm.html,
<div>
    <div>Hello</div>
</div>

N.

Peter Bacon Darwin

unread,
Nov 30, 2012, 12:06:43 PM11/30/12
to ang...@googlegroups.com

Check for whitespace in your template. You appear to have multiple top level dom nodes in it.

Pete
...from my mobile.

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.

Nash

unread,
Nov 30, 2012, 1:10:01 PM11/30/12
to ang...@googlegroups.com
Resolved - ended up being just a bad relative file path in django.  Looking at the server get request cleared this up.  Curiously, though, the debug output in chrome only gives a 404 (Not Found) response when using the leading slash for domain relative paths.  When I give it an invalid relative path (no leading slash) in the templateUrl the 404 error never fires and I get the previous "template must have exactly one root element..." error.  Is this common behavior?  

Either way, point is: check the server get response first to double check you're pointing to a valid file.
Message has been deleted

Aamir Nawaz

unread,
Jun 27, 2014, 2:20:43 AM6/27/14
to ang...@googlegroups.com
if we have to pass templateUrl through attrs then what to do?
currently I am doint like this
<tempurl path="GenInfoTemp.html"></tempurl>

.directive('tempurl', function () {
    return {
        restrict: 'E',
        scope: {
            path: '='
        },
        link: function (scope) {
            debugger;
            scope.$watch('source', function (element) {
                debugger;
                
            }, true);
        },
        templateUrl: function (scope,element,attrs) {
            debugger;
            attrs.path;
            return scope.path;
        }
    };
});

Martin Alix

unread,
Jun 28, 2014, 8:42:24 AM6/28/14
to ang...@googlegroups.com
Use template instead:
return {
...
template: function(tElement, tAttrs) {
tAttrs.path
}
...
}

See: https://code.angularjs.org/1.2.18/docs/api/ng/service/$compile#description_comprehensive-directive-api_directive-definition-object

Allandt Bik-Elliott

unread,
Feb 11, 2016, 11:55:14 AM2/11/16
to AngularJS, vai...@mac.com
Sorry to necro but Nobody mentioned <base>


This completely solved our issue:
<base href="{% static 'js/vendor/myapp/app/' %}" />
<script src="js/Module.js"></script>

and we left templateUrl the same in our directive:
(function () {
'use strict';
angular

   
.module('site.project.app')
   
.directive('myDirective', [myDirective])
;
function myDirective() {


   
return {
        restrict
: 'E',
        replace
: true,

        controller
: 'MyCtrl',
        templateUrl
: 'partials/my-directive.html',
        link
: function (scope, elem, attrs) {
       
}

   
}
}
})();    

                                                                                                                                                                ~

Phil Howley

unread,
Jul 25, 2016, 4:08:39 AM7/25/16
to AngularJS, vai...@mac.com
I wasted 1 hour because I mistyped templateUrl. You saved me from insanity. Thanks!
Reply all
Reply to author
Forward
0 new messages