~ read.

Encapsulating AngularJS templates with $templateCache and gulp

Whether we're creating libraries, frameworks, plugins or any piece of reusable code, we should be keeping two things in mind:

  1. The code should be clear and modular enough so that anyone can modify it to their application's needs.
  2. The code should be encapsulated enough so that anyone can grab the code and use it without having to touch a thing.

This post will be focusing on using the Angular $templateCache service that helps encapsulate reusable code that requires templates/views as a part of the code's reusability.

Prerequisites:

  1. Node/Node Package Manager(npm) installed on your machine.
  2. Familiarity with Angularjs concepts such as directives and run blocks.
  3. Some familiarity with build systems such as grunt or gulp.

What is the $templateCache service?

To put it simply, the $templateCache allows you to cache your templates so that they can later be retrieved quickly using a key.

This is particularly useful as complex angularjs applications are consistently making use of templates for ui-element directives and even ng-include directives in your html. Additionally, with the help of gulp's angular-template-cache module, it gets rid of the need for any of that nasty multi-line inline html in your javascript.

Instead of having to write the following:

app.directive('directiveName', function(){

  return {
  restrict: 'ECMA',
  link: function(scope, el, attr) {...},
  template: ""< div> Example Div < /div>"" +
  ""< div> Another Sample Div < /div>""  +
  ""< div> Another Sample Div < /div>""  +
  ...
  }
})

or

app.directive('directiveName', function(){

  return {
   restrict: 'ECMA',
   link: function(scope, el, attr) {...},
   templateUrl: 'some/relative/or/absolute/path/to/our/file.html' 
  }
})

We just inject the $templateCache into our directives and we retrieve the templates using the templateUrl property and our template key:

app.directive('directiveName', function($templateCache){

    return {
      restrict: 'ECMA',
      link: function(scope, el, attr) {...},
      templateUrl: 'homepage.html'
    }
})

In the above example, 'homepage.html' is just a string that we used as a key when storing our template. This is not referencing an actual file path to an html file. It's just common practice to use the file names as keys when inserting templates into the template cache.

So how do we store templates?

There are two ways to do this. The first way is to add them via a script tag in our html, however this defeats the purpose of encapsulating the templates in our javascript. Therefore we will focus on the second way which is to use $templateCache's put method:

  angular.module('testModule')
    .run(function($templateCache){
      $templateCache.put('test.html', '< div> Some HTML here < /div>')
    });

We will want to use templateCache in the run block of our angular applications so that everything gets cached early on and we don't have to worry about it again. However, there is an issue with the above example. It looks feasible when our value is only one line of html, but for most of us our html templates are far more complex than that and we wouldn't want to sit there manually concatenating html. This is where gulp comes in.

Gulp, like grunt, is a handy tool used to automate tasks that might otherwise be really arduous and annoying. In this case, we'll be using gulp to go through all our html files and write a $templateCache.put method for each html file where the key is name of the html file and the value is the entire template in one giant line. Fortunately, someone has already created an awesome module that does all that magic for us called gulp-angular-templatecache

First we'll need to install gulp using node package manager(npm). Run the following command in your terminal:

$ npm install gulp

Then we'll download gulp-angular-templatecache:

$ npm install gulp-angular-templatecache

Next, we'll need to create a gulpfile.js file in the root directory of our application. In the gulpfile.js we'll require in gulp, and gulp-angular-templatecache:

var gulp = require('gulp');
var templateCache = require('gulp-angular-templatecache');

Then we'll create the task like so:

gulp.task('templateCache', function () {
  gulp.src('templates/**/*.html')
   .pipe(templateCache())
   .pipe(gulp.dest('path/to/destination'));
});

In the above example, gulp.src takes a string as an argument that points to the location of all the files. gulp.dest takes a string as an argument that points to the destination where you want the concatenated methods to be written. If you leave templateCache() empty, gulp will create a templates.js file for you in the destination.

Now all we need to do is run the command in our terminal:

$ gulp templateCache

And voila, a script that will cache all your html templates can be pasted into the run block of your angular application.

Additional Resources:
Angular Docs

Awesome Video from Egghead

comments powered by Disqus