45

After the Angular app is loaded I need some of the templates to be available offline.

Something like this would be ideal:

$routeProvider
  .when('/p1', {
    controller: controller1,
    templateUrl: 'Template1.html',
    preload: true
  })
1

5 Answers 5

57

This is an addition to the answer by @gargc.

If you don't want to use the script tag to specify your template, and want to load templates from files, you can do something like this:

    myApp.run(function ($templateCache, $http) {
        $http.get('Template1.html', { cache: $templateCache });
    });

    myApp.config(function ($locationProvider, $routeProvider) {
        $routeProvider.when('/p1', { templateUrl: 'Template1.html' })
    });
Sign up to request clarification or add additional context in comments.

6 Comments

by the way, $http.get('Template1.html', {cache: $templateCache}); should have the same effect. Although, it does not really make much of a difference :)
This is definitely a simpler alternative than what I suggested. Thanks again :)
I prefer this solution as it doesn't require building a JavaScript file from HTML templates.
this line " $http.get('Template1.html', { cache: $templateCache });" also means that you add it to angular cache?
I've tried this out, but since the http.get is asynchronous my template hasn't been loaded yet on the point where I acutally need it. Anyone know how to work around that?
|
45

There is a template cache service: $templateCache which can be used to preload templates in a javascript module.

For example, taken from the docs:

var myApp = angular.module('myApp', []);
  myApp.run(function($templateCache) {
  $templateCache.put('templateId.html', 'This is the content of the template');
});

There is even a grunt task to pre-generate a javascript module from html files: grunt-angular-templates

Another way, perhaps less flexible, is using inline templates, for example, having a script tag like this in your index.html:

<script type="text/ng-template" id="templates/Template1.html">template content</script>

means that the template can be addressed later in the same way as a real url in your route configuration (templateUrl: 'templates/Template1.html')

5 Comments

Thanks, just what I was looking for! I would really like being able to specify the template file in $templateCache.put(), the script tag alternative messes up my IDE, and I'm not using grunt. I ended up using $http. See my own answer for details.
I haven't tested that Grunt plugin yet but ... does it include controllers as well? Or just the templates? Might be nice to preload everything possible, for loading views quickly. Thanks!
+1 for the Inline templates. The inline templates allow for faster initial load, but with the flexibility of replacing the content later.
@derrylwc: I am struggling with the opposite problem in the moment. I have an project, created with a grunt generator (grunt-angular-fullstack), which automatically includes and configures a lot of grunt tasks. One of them is grunt-angular-templates. As I want to intercept the loading from the server with my authentication framwork, I need the request to the server, but I do not get them. So yes, it also prloads the controller.js files.
In case your template needs to be fetched from a URL: myApp.run(function($templateRequest) { $templateRequest('/url/to/template.html', true); });
28

I think I have a slightly improved solution to this problem based on Raman Savitski's approach, but it loads the templates selectively. It actually allows for the original syntax that was asked for like this:

$routeProvider.when('/p1', { controller: controller1, templateUrl: 'Template1.html', preload: true })

This allows you to just decorate your route and not have to worry about updating another preloading configuration somewhere else.

Here is the code that runs on start:

angular.module('MyApp', []).run([
    '$route', '$templateCache', '$http', (function ($route, $templateCache, $http) {
        var url;
        for (var i in $route.routes) {
            if ($route.routes[i].preload) {
                if (url = $route.routes[i].templateUrl) {
                    $http.get(url, { cache: $templateCache });
                }
            }
        }
    })
]);

8 Comments

I would change it slightly to only not preload, if there's an explicit preload: false so the preloading is enabled for a route by default. But I think that descision is personal taste and depends on what you want to do. Besides that great snippet! +1
When I wrote that I was just wanting to load two routes out of about 20 or so. So, the explicit preload: true worked a little better for me.
This is by far the best answer.
I am very glad to find your response here..I been strugling to find a way to cache my templates..thanks
If, like me, you got here looking for a solution using uiRouter and like this idea: try this. It will load the template for the state and any views it has defined.
|
18

Preloads all templates defined in module routes.

angular.module('MyApp', [])
.run(function ($templateCache, $route, $http) {
    var url;
    for(var i in $route.routes)
    {
      if (url = $route.routes[i].templateUrl)
      {
        $http.get(url, {cache: $templateCache});
      }
    }
})

2 Comments

What happen if the content of the template changes dynamically? Is this showed properly or will show the same content as it comes from the cache?
If content is dynamic - there is no sense to "preload" it. Or I don't understand your case.
0

if you wrap each template in a script tag, eg:

<script id="about.html" type="text/ng-template">
<div>
    <h3>About</h3>
    This is the About page
    Its cool!
</div>
</script>

Concatenate all templates into 1 big file. If using Visual Studio 2013,Download Web essentials - it adds a right click menu to create an HTML Bundle

Add the code that this guy wrote to change the angular $templatecache service - its only a small piece of code and it works :-)

https://gist.github.com/vojtajina/3354046

Your routes templateUrl should look like this:

        $routeProvider.when(
            "/about", {
                controller: "",
                templateUrl: "about.html"
            }
        );

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.