Using $templateCache in AngularJS
Angular uses templates as the View part of their MVC design pattern. Templates allow to prepare the html context of where data from the controllers will be displayed.
Templates can be used as partials for the whole ng-view
based on the routing configuration, as well as for a directive to create components, or on the fly as a simple ng-include
.
There are multiple ways to declare a template to be chosen from. The choice usually depends on how readable such presentation is.
directly as a text block:
angular.directive('cartItem', function() {
return {
template: '<strong>Name:</strong> <strong>Price:</strong> '
};
});
as an inline script:
<script type="text/ng-template" id="cartItemTemplate">
<p><strong>Name:</strong> </p>
<p><strong>Price :</strong> </p>
</script>
<div ng-include="cartItemTemplate"></div>
as a remote url to an html file:
<div class="cart-item">
<p><strong>Name:</strong> </p>
<p><strong>Price :</strong> </p>
</div>
<div ng-include="'cartItem.tpl.html'"></div>
Introducing the $templateCache
Using many template files is a good way to organize the application code and separate the reusable parts in a clear structure. It comes however at a cost of multiple http requests needed to render a single page. This can slow down the performance considerably.
One way of combatting the surplus requests is the $templateCache.
$templateCache is angular’s build in key-value store for the template contents. When fetching a template declared by a remote url through ng-include
or templateUrl
, angular looks for it first in the $templateCache and if the template is found there it doesn’t perform the http request. Templates can be placed and fetched from the templateCache by simple put and get functions:
angular.module('myApp', []) .run(function($templateCache) {
$templateCache.put('cartItem.tpl.html', '<strong>Name:</strong> <strong>Price:</strong> ');
});
$templateCache.get('cartItem.tpl.html')
Automating template caching
Puting everything in the templateCache manually would bring us back to the first inline solution, with poor readability and it would make changing anything in a template a thankless task. Luckilly there are grunt and gulp plugins that enable autogenerating the templateCache in the build brocess.
gulp-angular-templatecache
var templateCache = require('gulp-angular-templatecache');
gulp.task('prepare:templates', function () {
return gulp.src('app/**/*.tpl.html')
.pipe(ngTemplates({
filename: 'templates.js',
module: 'myApp',
}))
.pipe(gulp.dest('dist'));
})
The above task reads all the *.tpl.html
files for the application and compiles them into templates.js
file which then can be included in the app.
window.app.run(["$templateCache", function($templateCache) {
$templateCache.put("CompanyChoice/CompanyChoice.tpl.html","<div>escaped contents</div>");
$templateCache.put("CompanyChoice/CompanyDescription.tpl.html","<div>escaped contents</div>");
}
]);
The process can be optimized further by singling out the critical templates which have to be served immidiately and lazy prefetching all the rest.