web-dev-qa-db-ja.com

AngularJSが開発マシンで部分キャッシュを無効にする

AngularJSでパーシャルのキャッシュに問題があります。

私のHTMLページには、次のものがあります。

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

私のパーシャルはどこにロードされます。

パーシャルのHTMLコードを変更しても、ブラウザは古いデータをロードします。

回避策はありますか?

210
Mennion

開発のためには、ブラウザのキャッシュを無効にすることもできます - Chrome Dev Toolsの右下にある歯車をクリックしてオプションをクリック

キャッシュを無効にする(DevToolsが開いている間)

更新:Firefoxでは、デバッガ - >設定 - >詳細セクションに同じオプションがあります(バージョン33でチェック済み)

アップデート2:このオプションはFirefoxに表示されますが、機能しません。私はFirebugを使ってhadaytullahの答えをフォローすることを勧めます。

201
LukeSolar

@Valentynの答えを少し基にして、ng-viewの内容が変更されるたびにキャッシュを常に自動的にクリアする方法の1つを次に示します。

myApp.run(function($rootScope, $templateCache) {
   $rootScope.$on('$viewContentLoaded', function() {
      $templateCache.removeAll();
   });
});
111
Mark Rajcok

他の回答、 here および here で述べたように、キャッシュは次のようにして消去できます。

$templateCache.removeAll();

しかし コメントgatoatigrado で示唆されているように、これはhtmlテンプレートがキャッシュヘッダなしで提供された場合にのみ機能するように見えます。

だからこれは私のために働く:

角度で:

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;   
}

編集

私は、質問がdev machineについて言及していることに気付きましたが、うまくいけばこれはまだ誰かに役立つかもしれません...

37
Chris Foster

ページ全体を再ロードせずにテンプレートのキャッシュに使用されるキャッシュについて話している場合は、次のようにして空にすることができます。

.controller('mainCtrl', function($scope, $templateCache) {
  $scope.clearCache = function() { 
    $templateCache.removeAll();
  }
});

そしてマークアップでは:

<button ng-click='clearCache()'>Clear cache</button>

そしてこのボタンを押してキャッシュをクリアします。

31

Firebug(22.0.6)を使用したFirefox(33.1.1)の解決策

  1. ツール> Webツール> Firebug> Firebugを開きます。
  2. Firebugのビューで、 "Net"ビューに行きます。
  3. ドロップダウンメニューの記号が[Net](ビューのタイトル)の横に表示されます。
  4. ドロップダウンメニューから[ブラウザキャッシュを無効にする]を選択します。
22
hadaytullah

このスニペットは私がテンプレートキャッシュを取り除くのを助けました

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/

19
Code Prank

他の解決策はどれも私のために働かなかったので、私はこれをすべての可能性をカバーするためにこれを投稿しています(それらはとりわけ角ブートストラップテンプレートの依存関係によるエラーを投げました)。

特定のテンプレートを開発/デバッグしている間は、次のようにパスにタイムスタンプを含めることで常に更新するようにすることができます。

       $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();
            };
          }
        });

templateUrl変数の最後の?nd=' + Date.now()に注意してください。

16
diosney

他の人が言っているように、開発目的のためにキャッシュを完全に無効にすることは、コードを変更することなく簡単に行うことができます。ブラウザ設定またはプラグインを使用します。 devの外で、ルートベースのテンプレートのAngularテンプレートキャッシュを無効にするには、Shayanが示したように$ routeChangeStart(またはUIルーターの場合は$ stateChangeStart)の間にキャッシュからテンプレートURLを削除します。ただし、ng-includeによってロードされたテンプレートのキャッシュには影響しません。これらのテンプレートはルータを通じてロードされないためです。

Ng-includeで読み込まれたものも含め、あらゆるテンプレートを本番環境で修正し、ユーザーがページ全体をリロードすることなくブラウザですばやく修正プログラムを受け取るようにしたいと思いました。私はテンプレート用のHTTPキャッシュを破ることも心配していません。解決策は、アプリが行うすべてのHTTPリクエストを傍受し、私のアプリの.htmlテンプレート用ではないHTTPリクエストを無視して、テンプレートのURLに毎分変わるparamを追加することです。パスチェックはアプリのテンプレートのパスに固有のものです。間隔を変えるには、パラメータの計算式を変更するか、%を完全に削除してキャッシュを行わないようにします。

// 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;
    }
11
bradw2k

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の "when"メソッドを装飾しても同じ結果が得られると確信しています。

8
Aman Mahajan

私は、HTTPインターセプターメソッドが非常にうまく機能し、追加の柔軟性と制御を可能にすることを発見しました。さらに、リリースハッシュをバスター変数として使用することで、プロダクションリリースごとにキャッシュバストすることができます。

これがdev cachebustingメソッドが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');
}]);
3
cpreid

これはChromeの他の選択肢です。

ヒット F12 開発者ツールを開く。それからリソース>キャッシュストレージ>キャッシュを更新します

enter image description here

他の答えのようにキャッシュを無効にする必要がないので、このオプションが好きです。

1
Jess

あなたはそれを制御することができないので、ブラウザ/プロキシキャッシュを防ぐための解決策はありません。

新鮮なコンテンツをユーザーに強制するもう1つの方法は、HTMLファイルの名前を変更することです。まさに https://www.npmjs.com/package/grunt-filerev のようになります。

0
Thomas Decaux