AngularJS désactiver la mise en cache partielle sur la machine dev
j'ai un problème avec la mise en cache des partiels dans AngularJS.
dans ma page HTML j'ai:
<body>
<div ng-view></div>
<body>
où mes partiels sont chargés.
quand je change le code HTML dans mon partiel, le navigateur charge toujours les anciennes données.
y a-t-il une solution?
13 réponses
pour le développement, vous pouvez également désactiver le cache navigateur-dans les outils Chrome Dev sur le clic droit en bas sur la vitesse et de cocher l'option
Désactiver le cache (alors que les DevTools est ouvert)
mise à jour: dans Firefox il y a la même option dans Debugger -> paramètres -> section avancée (cochée pour la Version 33)
mise à jour 2: Bien que cette option apparaisse dans Firefox certains signalent qu'elle ne fonctionne pas. Je suggérez d'utiliser firebug et de suivre la réponse de hadaytullah.
en S'appuyant un peu sur la réponse de @Valentyn, voici une façon de toujours vider automatiquement le cache chaque fois que le contenu de la vue ng change:
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
comme mentionné dans les autres réponses, ici et ici , le cache peut être nettoyé en utilisant:
$templateCache.removeAll();
cependant comme suggéré par Gat oatigrado dans le comment , cela ne semble fonctionner que si le modèle html a été servi sans aucun en-tête de cache.
donc ça marche pour moi:
en angle:
app.run(['$templateCache', function ( $templateCache ) {
$templateCache.removeAll(); }]);
vous pouvez ajouter des en-têtes de cache de différentes façons, mais voici quelques solutions qui fonctionnent pour moi.
si vous utilisez IIS
, ajoutez ceci à votre site web.config:
<location path="scripts/app/views">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
si vous utilisez Nginx, vous pouvez ajouter ceci à votre configuration:
location ^~ /scripts/app/views/ {
expires -1;
}
Modifier
je viens de réaliser que la question mentionnait dev
machine mais j'espère que ce mai encore aider quelqu'un...
si vous parlez de cache qui a été utilisé pour la mise en cache de gabarits sans recharger la page entière, alors vous pouvez le vider par quelque chose comme:
.controller('mainCtrl', function($scope, $templateCache) {
$scope.clearCache = function() {
$templateCache.removeAll();
}
});
et dans le markup:
<button ng-click='clearCache()'>Clear cache</button>
et appuyez sur ce bouton pour vider le cache.
Solution Pour Firefox 33.1.1) à l'aide de Firebug (22.0.6)
- Outils > Outils Internet > Firebug > Ouvrir Firebug.
- dans les vues coupe-feu aller à la vue" Net".
- un symbole de menu déroulant apparaîtra à côté de" Net " (titre de la vue).
- sélectionnez "Disable Browser Cache" dans le menu déroulant.
cet extrait m'a aidé à me débarrasser de la mise en cache de template
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (typeof(current) !== 'undefined'){
$templateCache.remove(current.templateUrl);
}
});
});
les détails de l'extrait suivant peuvent être trouvés sur ce lien: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs /
je poste ceci juste pour couvrir toutes les possibilités puisque aucune des autres solutions n'a fonctionné pour moi (ils ont lancé des erreurs dues à des dépendances angular-bootstrap template, entre autres).
pendant que vous développez / déboguez un modèle spécifique, vous pouvez vous assurer qu'il se rafraîchit toujours en incluant un timestamp dans le chemin, comme ceci:
$modal.open({
// TODO: Only while dev/debug. Remove later.
templateUrl: 'core/admin/organizations/modal-selector/modal-selector.html?nd=' + Date.now(),
controller : function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
}
});
Note finale ?nd=' + Date.now()
dans le templateUrl
à la variable.
comme d'autres l'ont dit, la suppression totale de la mise en cache pour les besoins du dev peut se faire facilement sans changer de code: utilisez un paramètre de navigateur ou un plugin. En dehors de dev, pour vaincre la mise en cache angulaire des templates basés sur les routes, supprimez L'URL du template du cache pendant $routeChangeStart (ou $stateChangeStart, pour UI Router) comme Shayan l'a montré. Cependant, cela n'affecte pas la mise en cache des gabarits chargés par ng-include, car ces gabarits ne sont pas chargés via le routeur.
j'ai voulu être en mesure de hotfix n'importe quel modèle, y compris ceux chargés par ng-include, en production et avoir les utilisateurs reçoivent le hotfix dans leur navigateur rapidement, sans avoir à recharger la page entière. Je ne me soucie pas non plus de vaincre la mise en cache HTTP pour les modèles. La solution est d'intercepter chaque requête HTTP que L'application fait, ignorer ceux qui ne sont pas pour mon application .modèles html, puis Ajouter un paramètre à L'URL du modèle qui change à chaque minute. Notez que l' path-checking est spécifique au path des modèles de votre application. Pour obtenir un intervalle différent, changez le calcul pour le param, ou supprimez le % complètement pour obtenir aucune mise en cache.
// this defeats Angular's $templateCache on a 1-minute interval
// as a side-effect it also defeats HTTP (browser) caching
angular.module('myApp').config(function($httpProvider, ...) {
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
config.url = getTimeVersionedUrl(config.url);
return config;
}
};
});
function getTimeVersionedUrl(url) {
// only do for html templates of this app
// NOTE: the path to test for is app dependent!
if (!url || url.indexOf('a/app/') < 0 || url.indexOf('.html') < 0) return url;
// create a URL param that changes every minute
// and add it intelligently to the template's previous url
var param = 'v=' + ~~(Date.now() / 60000) % 10000; // 4 unique digits every minute
if (url.indexOf('?') > 0) {
if (url.indexOf('v=') > 0) return url.replace(/v=[0-9](4)/, param);
return url + '&' + param;
}
return url + '?' + param;
}
si vous utilisez un routeur UI, alors vous pouvez utiliser un décorateur et mettre à jour le service $templateFactory et Ajouter un paramètre de chaîne de requête à templateUrl, et le navigateur chargera toujours le nouveau modèle à partir du serveur.
function configureTemplateFactory($provide) {
// Set a suffix outside the decorator function
var cacheBust = Date.now().toString();
function templateFactoryDecorator($delegate) {
var fromUrl = angular.bind($delegate, $delegate.fromUrl);
$delegate.fromUrl = function (url, params) {
if (url !== null && angular.isDefined(url) && angular.isString(url)) {
url += (url.indexOf("?") === -1 ? "?" : "&");
url += "v=" + cacheBust;
}
return fromUrl(url, params);
};
return $delegate;
}
$provide.decorator('$templateFactory', ['$delegate', templateFactoryDecorator]);
}
app.config(['$provide', configureTemplateFactory]);
je suis sûr que vous pouvez obtenir le même résultat en décorant la méthode" quand " dans $routeProvider.
j'ai trouvé que la méthode HTTP interceptor fonctionne assez bien, et permet une flexibilité et un contrôle supplémentaires. En outre, vous pouvez cache-bust pour chaque version de production en utilisant un hachage de version comme variable de buster.
voici à quoi ressemble la méthode dev cachebusting en utilisant Date
.
app.factory('cachebustInjector', function(conf) {
var cachebustInjector = {
request: function(config) {
// new timestamp will be appended to each new partial .html request to prevent caching in a dev environment
var buster = new Date().getTime();
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');
}]);
Voici une autre option dans Chrome.
Hit F12 pour ouvrir les outils de développement. Puis Ressources > Cache De Stockage > "151950920 D'Actualisation" Caches .
j'aime cette option parce que je n'ai pas à désactiver le cache comme dans les autres réponses.
il n'y a pas de solution pour empêcher la mise en cache par navigateur/proxy puisque vous ne pouvez pas avoir le contrôle dessus.
l'autre façon de forcer le contenu frais à vos utilisateurs il pour renommer le fichier HTML! Exactement comme https://www.npmjs.com/package/grunt-filerev fait pour les actifs.
Actualiser le document à toutes les 30 secondes:
<head>
<meta http-equiv="refresh" content="30">
</head>