Search code examples
angularjsangularjs-ng-include

$templateCache, $templateRequest, ngInclude play nice(er) together


I'm trying to get all my partials at first page view, so that during application viewing no html is downloaded.

One way is by having templates in index.html.

<script type="text/ng-template" id="templateId.html">
  <p>This is the content of the template</p>
</script>
  • This way is you have more than 5 templates index.html file becomes unmanageable and breaks module structure of project.

Another way of doing this is to have html in .js file, most likely in app.js

myApp.run(function($templateCache) {
  $templateCache.put('templateId.html', 'This is the content of the template');
});
  • I think .js file is no place for html code and again same problems as with having it in index.html.

What I would like to do, is have templates in different files, so I can keep my modules structure and preload them on index.

This is what I have now.

var cmsAppFirstRun = function ($templateCache, $templateRequest, $rootScope) {
    $templateRequest('views/common/top-bar.html').then(function (response) {
        $templateCache.put('top.bar', response);
        $rootScope.templatesDone = true;
    });
};

angular.module('cmsApp').run(cmsAppFirstRun);

And html

<div ng-include="'top.bar'" ng-if="$root.templatesDone"></div>

Is there a more sexy, angularish way of doing this?


Solution

  • Found some techniques using $http and $route in stack answers.

    I think most appealing is

    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});
          }
        }
    })
    

    This way all templates in route are loaded on first run.


    EDIT: I'm using UI Router so thing look a bit different in angular.run() block. Nested views not handled here yet.

    angular.forEach($state.get(), function(state){
                if(state.templateUrl){
                    $http.get(state.templateUrl, {cache: $templateCache});
                }
            });
    

    EDIT 2: I've missed $templateRequest that can be path to html template in angular.run() block.

     $templateRequest('views/cart/modal-confirm-continue-printing.html');
     $templateRequest('views/cart/modal-confirm-trash.html');
    

    EDIT 3: Since i build applications with grunt, i find https://www.npmjs.com/package/grunt-angular-templates usefoul for automating this process.