Files
ionic-framework/js/angular/service/templateCache.js

126 lines
3.9 KiB
JavaScript

// closure to keep things neat
(function() {
var templatesToCache = [];
/**
* @ngdoc service
* @name $ionicTemplateCache
* @module ionic
* @description A service that preemptively caches template files to eliminate transition flicker and boost performance.
* @usage
* State templates are cached automatically, but you can optionally cache other templates.
*
* ```js
* $ionicTemplateCache('myNgIncludeTemplate.html');
* ```
*
* Optionally disable all preemptive caching with the `$ionicConfigProvider` or individual states by setting `prefetchTemplate`
* in the `$state` definition
*
* ```js
* angular.module('myApp', ['ionic'])
* .config(function($stateProvider, $ionicConfigProvider) {
*
* // disable preemptive template caching globally
* $ionicConfigProvider.prefetchTemplates(false);
*
* // disable individual states
* $stateProvider
* .state('tabs', {
* url: "/tab",
* abstract: true,
* prefetchTemplate: false,
* templateUrl: "tabs-templates/tabs.html"
* })
* .state('tabs.home', {
* url: "/home",
* views: {
* 'home-tab': {
* prefetchTemplate: false,
* templateUrl: "tabs-templates/home.html",
* controller: 'HomeTabCtrl'
* }
* }
* });
* });
* ```
*/
IonicModule
.factory('$ionicTemplateCache', [
'$http',
'$templateCache',
'$timeout',
'$ionicConfig',
function($http, $templateCache, $timeout, $ionicConfig) {
var toCache = templatesToCache,
hasRun = false;
function $ionicTemplateCache(templates){
if(toCache.length > 500) return false;
if(typeof templates === 'undefined')return run();
if(isString(templates))templates = [templates];
forEach(templates, function(template){
toCache.push(template);
});
// is this is being called after the initial IonicModule.run()
if(hasRun) run();
}
// run through methods - internal method
var run = function(){
if($ionicConfig.prefetchTemplates === false)return;
//console.log('prefetching', toCache);
//for testing
$ionicTemplateCache._runCount++;
hasRun = true;
// ignore if race condition already zeroed out array
if(toCache.length === 0)return;
//console.log(toCache);
var i = 0;
while ( i < 5 && (template = toCache.pop()) ) {
// note that inline templates are ignored by this request
if (isString(template)) $http.get(template, { cache: $templateCache });
i++;
}
// only preload 5 templates a second
if(toCache.length)$timeout(function(){run();}, 1000);
};
// exposing for testing
$ionicTemplateCache._runCount = 0;
// default method
return $ionicTemplateCache;
}])
// Intercepts the $stateprovider.state() command to look for templateUrls that can be cached
.config([
'$stateProvider',
'$ionicConfigProvider',
function($stateProvider, $ionicConfigProvider) {
var stateProviderState = $stateProvider.state;
$stateProvider.state = function(stateName, definition) {
// don't even bother if it's disabled. note, another config may run after this, so it's not a catch-all
if(typeof definition === 'object' && $ionicConfigProvider.prefetchTemplates() !== false){
var enabled = definition.prefetchTemplate !== false;
if(enabled && isString(definition.templateUrl))templatesToCache.push(definition.templateUrl);
if(angular.isObject(definition.views)){
for (var key in definition.views){
enabled = definition.views[key].prefetchTemplate !== false;
if(enabled && isString(definition.views[key].templateUrl)) templatesToCache.push(definition.views[key].templateUrl);
}
}
}
return stateProviderState.call($stateProvider, stateName, definition);
};
}])
// process the templateUrls collected by the $stateProvider, adding them to the cache
.run([
'$ionicTemplateCache',
function($ionicTemplateCache) {
$ionicTemplateCache();
}]);
})();