Serving AngularJS templates from static resources

An AngularJS app typically starts with an “index” page that loads the required JavaScript/CSS and acts as the container for the client-side processed content. The app operates by rendering various templates in response to user interactions into that container.

That “index” page is a good place to obtain information from the “Visualforce” world that can be passed to the “AngularJS” world, and so is best made a Visualforce page. (See Passing platform configuration to an AngularJS app.)

But what about the templates? Typically there are many of these. Should they also be Visualforce pages? At first sight it seems a reasonable thing to do as the templates are “partial pages”. And Visualforce pages have fixed URLs whereas static resources have URLs that include a timestamp making them harder to reference in JavaScript code such as a route provider. And if you use individual static resources per template (rather than a ZIP static resource containing all the templates) each template has its own timestamp.

But providing a clear separation has been made between server-side processing and client-side processing, no Visualforce capabilities are needed for the templates. And using Visualforce pages adds complexity such as requiring profiles to be updated. So how can the static resource timestamp value be handled if static resources are used instead?

The answer is surprisingly simple: it appears that using the current (JavaScript) timestamp is enough to get the latest version. So a $routeProvider templateUrl for a static resource called “xyz_partial” is simply:

templateUrl: '/resource/' + Date.now() + '/xyz_partial'

You can see this pattern applied in this (quite new) Salesforce AngularJS sample application created by Pat Patterson.

PS As David Esposito comments, where there are only a small number of resource references, it is arguably cleaner to not use this timestamp approach.

Advertisements

4 thoughts on “Serving AngularJS templates from static resources

  1. A more supported way to get the URL is to use $Resource.MyResource rather than fiddling with the Date.now(). This is similar to what you had in your previous post (https://force201.wordpress.com/2014/04/11/passing-platform-configuration-to-an-angularjs-app/) — this is how we do it:

    //In the VF page
    var appConfig = {
    appResourceUrl : ‘{!URLFOR($Resource.SeatSelector)}’,
    }
    myApp.constant(‘appConfig’, appConfig);

    //Then, within app.js
    var myApp = angular.module(‘myApp’, [‘ngRoute’]);

    myApp.config(
    [‘$routeProvider’, ‘appConfig’,
    function($routeProvider, appConfig) {
    $routeProvider.
    when(‘/myList’, {
    templateUrl: appConfig.appResourceUrl + ‘/app/partials/myList.html’,
    controller: ‘MyListCtrl’
    }).
    ….

  2. Yes if the templates are all in a zip file your code makes sense and there isn’t much overhead. I’ll update the post to emphasise that the Date.now() approach is particularly beneficial where individual static resources are used per template (as a way of making development simpler by avoiding the zip step).

  3. I will say this is awesome stuff I have ever seen in salesforce world. I was java developer before, and chasing cool thing like your build.

    My question is I tried two ways of that,
    1. using abstract nest view in angularjs, not working, but got the response from static resource html template;
    2. using views with ui-router as well, working, but very slow, compares to use visual force component;
    3. for loading a html file or js file, why don’t use the path /resource/JS , it is gonna to give you the latest file as well ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s