AngularJS отключает частичное кэширование на dev-машине
У меня проблема с частицами кеширования в AngularJS.
На моей странице HTML у меня есть:
<body>
<div ng-view></div>
<body>
где мои частичные файлы загружены.
Когда я меняю HTML-код в своем частичном, браузер все еще загружает старые данные.
Есть ли способ обхода?
Ответы
Ответ 1
Для разработки вы также можете деактивировать кеш браузера. В Chrome Dev Tools в правом нижнем правом углу нажмите на передачу и отметьте опцию
Отключить кеш (пока DevTools открыт)
Обновление: в Firefox есть такая же опция в Debugger → Settings → Advanced Section (проверена для версии 33)
Обновление 2: Хотя эта опция появляется в Firefox, некоторые отчеты не работают. Я предлагаю использовать firebug и после ответа hadaytullah.
Ответ 2
Основываясь на @Valentyn, ответьте немного, здесь один способ всегда автоматически очищать кеш при изменении содержимого ng-view:
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
Ответ 3
Как уже упоминалось в других ответах, здесь и здесь, кеш можно очистить, используя:
$templateCache.removeAll();
Однако, как было предложено gatoatigrado в comment, это только работает, если шаблон html был отправлен без заголовков кеша.
Итак, это работает для меня:
В angular:
app.run(['$templateCache', function ( $templateCache ) {
$templateCache.removeAll(); }]);
Вы можете добавлять заголовки кеша различными способами, но здесь есть несколько решений, которые работают для меня.
Если вы используете IIS
, добавьте это в свой web.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
машиной, но, надеюсь, это может помочь кому-то...
Ответ 4
Если вы говорите о кеше, который был использован для кэширования шаблонов без перезагрузки всей страницы, вы можете его очистить чем-то вроде:
.controller('mainCtrl', function($scope, $templateCache) {
$scope.clearCache = function() {
$templateCache.removeAll();
}
});
И в разметке:
<button ng-click='clearCache()'>Clear cache</button>
И нажмите эту кнопку, чтобы очистить кеш.
Ответ 5
Решение для Firefox (33.1.1) с использованием Firebug (22.0.6)
- Инструменты > Веб-инструменты > Firebug > Open Firebug.
- В представлениях Firebug перейдите в представление "Net".
- Рядом с "Net" (название представления) появится значок выпадающего меню.
- Выберите "Отключить кеш браузера" в раскрывающемся меню.
Ответ 6
Этот фрагмент помог мне избавиться от кэширования шаблонов
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/
Ответ 7
Я публикую это только для того, чтобы охватить все возможности, так как ни один из других решений не работал у меня (они бросили ошибки из-за зависимостей шаблона angular -bootstrap, среди прочего).
Пока вы разрабатываете/отлаживаете определенный шаблон, вы можете убедиться, что он всегда обновляется, включая метку времени в пути, например:
$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
.
Ответ 8
Как говорили другие, полное уничтожение кэширования для целей dev может быть легко выполнено без изменения кода: используйте настройку браузера или плагин. Вне dev, чтобы победить Angular кэширование шаблонов шаблонов на основе маршрутов, удалите URL-адрес шаблона из кэша во время $routeChangeStart (или $StateChangeStart, для UI Router), как показал Шаян. Однако это НЕ влияет на кэширование шаблонов, загруженных ng-include, потому что эти шаблоны не загружаются через маршрутизатор.
Я хотел бы иметь возможность исправлять любой шаблон, включая те, которые были загружены ng-include, в процессе производства, и пользователи быстро получают исправление в своем браузере, не перезагружая всю страницу. Я также не заинтересован в том, чтобы победить HTTP-кеширование для шаблонов. Решение состоит в том, чтобы перехватывать каждый HTTP-запрос, который делает приложение, игнорировать те, которые не подходят для моих шаблонов .html приложения, а затем добавлять параметр к URL-адресу шаблона, который меняется каждую минуту. Обратите внимание, что проверка пути специфична для пути к вашим шаблонам приложений. Чтобы получить другой интервал, измените математику для параметра или полностью удалите%, чтобы не получить кеширование.
// this defeats Angular $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 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;
}
Ответ 9
Если вы используете UI-маршрутизатор, вы можете использовать декоратор и обновить службу $templateFactory и добавить параметр строки запроса в 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]);
Я уверен, что вы можете достичь такого же результата, украсив метод "когда" в $routeProvider.
Ответ 10
Я обнаружил, что метод перехватчика HTTP работает очень красиво, и обеспечивает дополнительную гибкость и контроль. Кроме того, вы можете использовать кеш-память для каждой производственной версии, используя хеш-релиз в качестве переменной-бустера.
Вот как выглядит метод кэширования dev, используя 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');
}]);
Ответ 11
Нет никакого решения предотвратить кеширование браузера/прокси, поскольку вы не можете управлять им.
Другой способ заставить свежий контент вашим пользователям переименовать HTML файл! Точно как https://www.npmjs.com/package/grunt-filerev для активов.
Ответ 12
Вот еще один вариант в Chrome.
Нажмите F12, чтобы открыть инструменты разработчика. Затем Ресурсы > Хранение кэша > Обновить кеши.
![введите описание изображения здесь]()
Мне нравится эта опция, потому что мне не нужно отключать кеш, как в других ответах.
Ответ 13
Обновить документ каждые 30 секунд:
<head>
<meta http-equiv="refresh" content="30">
</head>
w3schools HTML-атрибут http-equiv