[es|en]

Using JST as a source of Angular templates

If you're using Rails, a nice tool to expose your Javascript templates is JST. JST allows you to write HTML templates for your JS library of choice, and it exposes them in a JST global object on the client side, using their path relative to the Javascript asset's path as the key. They play nicely with Angular.js and there's a way to make Angular "JST aware" so to speak.

Usually, if you're writing some piece of Angular code that uses a template like a directive or a route, you would be able to use your JST templates writing something like:

angular.module('app')
  .directive('someDirective', function() {
    return {
      template: JST['some/template/path']()
    };
  });

This would execute the template function generated by JST, generate the HTML and set it as the directive's template. This is all fine, but let's look at some other ways of doing it.

When we try to find a template with an URL, Angular's first step is to look for it on its $templateCache. If it can't find it, it will try to fetch it from the server. Knowing that, we can manually inject our templates in the $templateCache:

angular.module('app')
  .directive('someDirective', function() {
    return {
      templateUrl: 'some/template/path'
    };
  })
  .run(['$templateCache', function($templateCache) {
    $templateCache.put('some/template/path', JST['some/template/path']);
  }]);

In this case, we're providing the $templateCache directly with a function that will generate the template. Angular will find and use it when looking for that templateUrl. Now, this is all very repetitive, and we can avoid it by decorating the $templateCache that is used all over Angular to make it try and fetch from JST first.

angular.module('app')
  .config(['$provide', function($provide) {
    $provide.decorator('$templateCache', function ($delegate) {
        var get = $delegate.get;

        $delegate.get = function (key) {
            return JST[key] || get(key);
        }

        return $delegate;
    });
  }]);

And that's it! From then on, you can use a JST key anywhere you'd use a template URL and Angular will automatically take it from JST.

powered byDisqus