В AngularJS отключить частичное кэширование на компьютере разработчика
У меня проблема с кэшированием партиалов в AngularJS.
в моей HTML-странице у меня есть:
<body>
<div ng-view></div>
<body>
где мои частичные загрузки.
когда я изменяю HTML-код в моем частичном, браузер по-прежнему загружает старые данные.
есть ли обходной путь?
13 ответов:
для разработки вы также можете отключить кэш браузера-в Chrome Dev Tools в правом нижнем углу нажмите на шестеренку и отметьте опцию
отключить кэш (пока DevTools открыт)
обновление: в Firefox есть такая же опция в отладчике - > настройки - > расширенный раздел (проверено для версии 33)
обновление 2: хотя эта опция появляется в Firefox, некоторые отчеты не работают. Я предлагаю использовать firebug и следующее хадайтулла отвечает.
основываясь на ответе @Valentyn немного, вот один из способов всегда автоматически очищать кэш всякий раз, когда изменяется содержимое ng-view:
myApp.run(function($rootScope, $templateCache) { $rootScope.$on('$viewContentLoaded', function() { $templateCache.removeAll(); }); });
как упоминалось в других ответах,здесь и здесь, кэш может быть очищен с помощью:
$templateCache.removeAll();
однако, как предложил gatoatigrado на комментарий, это работает только в том случае, если шаблон html был подан без каких-либо заголовков кэша.
так что это работает для меня:
в угловое:
app.run(['$templateCache', function ( $templateCache ) { $templateCache.removeAll(); }]);
вы можете добавлять заголовки кэширования различными способами, но вот несколько решений, которые работают для меня.
при использовании
IIS
добавьте это к вашей веб.config:<location path="scripts/app/views"> <system.webServer> <staticContent> <clientCache cacheControlMode="DisableCache" /> </staticContent> </system.webServer> </location>
если вы используете Nginx, вы можете добавить это в свою конфигурацию:
location ^~ /scripts/app/views/ { expires -1; }
Edit
Я только что понял, что вопрос упомянул
dev
машина, но, надеюсь, это может помочь кому-то...
Если вы говорите о кэше, который используется для кэширования шаблонов без перезагрузки всей страницы, то вы можете очистить его чем-то вроде:
.controller('mainCtrl', function($scope, $templateCache) { $scope.clearCache = function() { $templateCache.removeAll(); } });
и в разметке:
<button ng-click='clearCache()'>Clear cache</button>
и нажмите эту кнопку, чтобы очистить кэш.
решение для Firefox (33.1.1) с помощью Firebug (22.0.6)
- Инструменты > Web-Tools > Firebug > Open Firebug.
- в представлениях Firebug перейдите к представлению" Net".
- символ выпадающего меню появится рядом с" Net " (название представления).
- выберите "Отключить кэш браузера" из выпадающего меню.
этот фрагмент помог мне избавиться от кэширования шаблонов
app.run(function($rootScope, $templateCache) { $rootScope.$on('$routeChangeStart', function(event, next, current) { if (typeof(current) !== 'undefined'){ $templateCache.remove(current.templateUrl); } }); });
подробности следующего фрагмента можно найти по этой ссылке: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/
я публикую это только для того, чтобы охватить все возможности, поскольку ни одно из других решений не работало для меня (они бросали ошибки из-за зависимостей шаблона угловой загрузки, среди прочего).
в то время как вы разрабатываете/отлаживаете определенный шаблон, вы можете убедиться, что он всегда обновляется, включив метку времени в путь, например:
$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(); }; } });
отметить
?nd=' + Date.now()
наtemplateUrl
переменной.
Как уже говорили другие, полное уничтожение кэширования для целей разработки можно легко сделать без изменения кода: используйте настройки браузера или плагин. За пределами dev, чтобы победить Угловое кэширование шаблонов на основе маршрутов, удалите URL-адрес шаблона из кэша во время $routeChangeStart (или $stateChangeStart, для маршрутизатора пользовательского интерфейса), как показал Шаян. Однако это не влияет на кэширование шаблонов, загруженных ng-include, потому что эти шаблоны не загружаются через обращать в бегство.
Я хотел быть в состоянии исправить любой шаблон, в том числе загруженные ng-include, в производстве и пользователи получают исправление в своем браузере быстро, без необходимости перезагрузки всей страницы. Я также не беспокоюсь о победе над HTTP-кэшированием для шаблонов. Решение состоит в том, чтобы перехватывать каждый HTTP-запрос, который делает приложение, игнорировать те, которые не для моего приложения .html-шаблоны, затем добавьте параметр в URL-адрес шаблона, который меняется каждую минуту. Обратите внимание, что проверка пути зависит от пути шаблонов вашего приложения. Чтобы получить другой интервал, измените математику для параметра или полностью удалите%, чтобы не получить кэширование.
// 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; }
Если вы используете UI router, то вы можете использовать декоратор и обновить $templateFactory service и добавить параметр строки запроса к templateUrl, и браузер всегда будет загружать новый шаблон с сервера.
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]);
Я уверен, что вы можете достичь того же результата, украсив метод "when" в $routeProvider.
я обнаружил, что метод перехватчика HTTP работает довольно хорошо, и позволяет дополнительную гибкость и контроль. Кроме того, вы можете кэшировать перебор для каждого производственного выпуска, используя хэш выпуска в качестве переменной buster.
вот что метод этого установите разработчиков выглядит, как с помощью
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'); }]);
нет решения для предотвращения кэширования браузера / прокси, так как вы не можете иметь контроль над ним.
другой способ заставить свежий контент для ваших пользователей переименовать HTML-файл! Точно так же, как https://www.npmjs.com/package/grunt-filerev делает для активов.