1

I have a problem that occurs sometimes, when the template entry is not defined in the template cache, it happens every once in a while after reloading the page.

The related code:

index.html

<div ng-include src="'Views/templates.html'"></div>

Views/templates.html

<script type="text/ng-template" id="customTemplate/spare-request-item.html">    
  <div>..</div>
</script>

directive.js

.directive("spare", function ($templateCache) {
console.log($templateCache.info());, //return length 30 when it fails, 31 otherwise
console.log($templateCache.get('customTemplate/spare-request-item.html'));//return undefined when it fails
return {
    ..
    templateUrl: 'customTemplate/spare-request-item.html',

Anyone else has experienced this or know how to assure that the template is loaded and parsed before the directive runs? It is a angular bug?

5
  • what is the question? Where is the problem? And what are you trying to do? Commented Mar 11, 2015 at 19:43
  • I don't understand... you have an html file and within that the entire HTML is wrapped in an ng-template script ? To what end ? Commented Mar 11, 2015 at 19:46
  • @OmriAharon Basically I pretend to use a single file (templates.html), in the middle of that I got this error, I put the template in a single file to be sure that is has nothing to do with multiple templates in a single file. Commented Mar 11, 2015 at 19:53
  • Why not just have templateUrl: 'templates.html' in the directive then and remove the script wrapper ? Commented Mar 11, 2015 at 19:59
  • That should work, I think, but like I said, I pretend to put several templates in one file, to avoid too many http requests and having multiple tiny templates files, anyway I also have a similar code to replace an inline defined template the same way and that template works always. Commented Mar 11, 2015 at 20:02

1 Answer 1

1

Angular compiles the directives as it goes over DOM. You can't have it "wait" on a directive. What you could do, is not to show the directive until templates have loaded.

I don't think this is a good approach since it requires "knowledge" on the part of the user of the directive:

<div ng-include="'Views/templates.html'" 
     onload="$root.templatesLoaded = true"></div>

<my-directive ng-if="templatesLoaded"></my-directive>

Another approach would be to manually load all the templates and the directive's specific template. Here's a conceptual way of how to do this:

app.directive("foo", function($templateRequest, $templateCache, $compile) {
  return {
    link: function(scope, element) {
      $templateRequest("templates.html")
        .then(function(templateContainer) {
          $compile(templateContainer);
          return undefined; // just to show that no need to return anything
        })
        .then(function() {
          var template = $templateCache.get("foo.html");
          if (template) {
            element.html(template);
            $compile(element.contents())(scope);
          }
        });
    }
  }
});

plunker

$templateRequest is used here since it caches the templates.html template (to prevent double-requests), but it is a "lazy" use, since you would not actually need the template with id === "templates.html".

You can abstract it into a service, of course, to make it nicer.

Typically, however, I have seen directive developers embed the template in the .js file of the directive. This frees the user of the directive from loading separate .html files to make the directives work. I suppose you could load themes this way.

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

4 Comments

Thanks for the idea, but for some reason, that renders different when the template get loaded that way, I suppose I'm gonna put the template in the js, it was not my intention because viewing/editing a multiline string in javascript is not the nicest thing in the world.
@MatiasMolina, not sure why it renders differently - it shouldn't. If you can replicate in jsfiddle/plunker, I can take a look. Yes, editing template as a string is a pain, but that's why there are dev-time concerns and run-time concerns. There are tools (I'm not sure exactly what) that help merge templates into their respective .js during deployment
@MatiasMolina, did you resolve your issue? If the answer helped, consider accepting
I finally put into the template cache the template as a multiline javascript string in a module, that the directive module referenced like a dependency. Even if I didn't find out why it failed randomly to load/parse the template, I guess you pushed me in the final direction.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.