6

I'm in proccess of development site, but every time i upload a new version to my server the users need to clean there cache to see the changes, what is the solution to this problem?

I try two ways to solve this thing from answers to questions here:

The first way:

myApp.run(function($rootScope, $templateCache) {
   $rootScope.$on('$viewContentLoaded', function() {
      $templateCache.removeAll();
   });
});

But this way have a problem with things like ui.bootstrap and its throw error.

The second way:

$rootScope.$on("$stateChangeStart", function( event, toState, current ) {

    if (typeof(current) !== 'undefined'){
      $templateCache.remove(current.templateUrl);
    }
})

This not throw error, but i dont know if this solution is the right one and if it work, what i need to do?

4
  • 1
    You can add an $http interceptor and set cache to false for all html based calls. Commented Dec 25, 2014 at 13:04
  • And this is will make to all my ui router partials to not be cached? Commented Dec 25, 2014 at 13:08
  • Yes, that will not cache any partials. But after reading your question, it looks like, it is an browser caching issue not angular caching. Well try using interceptors then will see. Commented Dec 25, 2014 at 13:12
  • Just to clarify, do you want the partials to update without having users reload the app (if they reloaded, it starts loading from scratch)? Commented Dec 25, 2014 at 16:16

2 Answers 2

4

This is a problem with the server configuration, and how it tells the browser to cache the HTML files used as template partials.

Understanding Browser Caching

You are attempting to do $templateCache.remove(..) and $templateCache.removeAll() which is not going to work, because the templates haven't been loaded yet, or the browser will just reload them using the cached version.

You need to check the network history in the browser to ensure that the server is handling HTML requests correctly. Send the header settings for caching that you expected. For each partial, there should be a 302 (not modified) response. When the HTML file has changed then the server should send the new modified one to the browser.

The other problem is your default cache duration on the server might be too long. This tells the browser how often it should check the server to send new versions of the HTML file. You might want to reduce this duration to 1 hour.

Most web servers are pre-configured to assume a file with the extension .html will never change and is static. So the default settings are to have the browser cache those files for as a long as possible.

You might want to rename those files to something like .ahtml and use that as your partial file names. There shouldn't be any pre-defined configuration to force cashing of those file types.

Understanding $templateCache

This is a very simple cache service in AngularJS. If the URL is not found in memory it is loaded from the server. The next time that partial is needed while the app is running the memory version is used. The usage of this server has nothing to do with server/browser caching.

Templates The Right Way

It's a best practice to create a single JavaScript file that contains all the partial templates the application will need. This JS file will call the $templateCache service and add those templates. This improves the startup performance of your application, and removes the problem of dealing with server/browser caching.

There are several grunt tasks that can do this.

https://www.npmjs.com/package/grunt-angular-templates

https://github.com/karlgoldstein/grunt-html2js

Combine this will a JavaScript minifier and concat all your JS into a single file, and you're well on your way.

Sign up to request clarification or add additional context in comments.

Comments

0

Here is a pretty straight-forward way to do this. Each deployment has a unique hash, which get's used within an HTTP interceptor to request new partial templates for each production release:

app.factory('cachebustInjector', function(conf) {
    // generated each deploy   
    var buster = 'kaqreFZ3MWcGzfS86iSiud'; 

    var cachebustInjector = {
        request: function(config) {    
            if (config.url.indexOf('static/angular_templates') > -1) {
                config.url += ['?v=', buster].join('');
            }
            return config;
        }
    };
    return cachebustInjector;
});

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('cachebustInjector');
}]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.