В AngularJS отключить частичное кэширование на компьютере разработчика


У меня проблема с кэшированием партиалов в AngularJS.

в моей HTML-странице у меня есть:

<body>
 <div ng-view></div>
<body>

где мои частичные загрузки.

когда я изменяю HTML-код в моем частичном, браузер по-прежнему загружает старые данные.

есть ли обходной путь?

13 209

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)

  1. Инструменты > Web-Tools > Firebug > Open Firebug.
  2. в представлениях Firebug перейдите к представлению" Net".
  3. символ выпадающего меню появится рядом с" Net " (название представления).
  4. выберите "Отключить кэш браузера" из выпадающего меню.

этот фрагмент помог мне избавиться от кэширования шаблонов

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');
}]);

вот еще один вариант в Chrome.

нажмите F12 открыть инструменты разработчика. Тогда ресурсы>Кэш Хранения>Обновить Кэши.

enter image description here

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

нет решения для предотвращения кэширования браузера / прокси, так как вы не можете иметь контроль над ним.

другой способ заставить свежий контент для ваших пользователей переименовать HTML-файл! Точно так же, как https://www.npmjs.com/package/grunt-filerev делает для активов.

обновлять документ каждые 30 секунд:

<head>
  <meta http-equiv="refresh" content="30">
</head>

W3Schools HTML http-equiv атрибут