Reputation: 35
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?
Upvotes: 1
Views: 1143
Reputation: 49590
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);
}
});
}
}
});
$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.
Upvotes: 1