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, чтобы открыть инструменты разработчика. Затем Ресурсы > Хранение кэша > Обновить кеши.

введите описание изображения здесь

Мне нравится эта опция, потому что мне не нужно отключать кеш, как в других ответах.