AngularJSでパーシャルをキャッシュすることに問題があります。
私のHTMLページには次のものがあります。
<body>
<div ng-view></div>
<body>
私のパーシャルがロードされる場所。
パーシャルのHTMLコードを変更しても、ブラウザは古いデータをロードし続けます。
回避策はありますか?
AngularJSでパーシャルをキャッシュすることに問題があります。
私のHTMLページには次のものがあります。
<body>
<div ng-view></div>
<body>
私のパーシャルがロードされる場所。
パーシャルのHTMLコードを変更しても、ブラウザは古いデータをロードし続けます。
回避策はありますか?
開発の場合、ブラウザのキャッシュを無効にすることもできます - 右下の Chrome Dev Tools で歯車をクリックし、オプションにチェックマークを付けます
キャッシュを無効にする (DevTools が開いている間)
更新: Firefox では、Debugger -> Settings -> Advanced Section (バージョン 33 をチェック) に同じオプションがあります。
更新 2: このオプションは Firefox に表示されますが、一部のレポートでは機能しません。firebug を使用し、hadaytullah の回答に従うことをお勧めします。
@Valentynの回答に少し基づいて、ng-viewコンテンツが変更されるたびに常に自動的にキャッシュをクリアする1つの方法を次に示します。
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
ページ全体をリロードせずにテンプレートのキャッシュに使用されているキャッシュについて話している場合は、次のようにして空にすることができます。
.controller('mainCtrl', function($scope, $templateCache) {
$scope.clearCache = function() {
$templateCache.removeAll();
}
});
そしてマークアップで:
<button ng-click='clearCache()'>Clear cache</button>
このボタンを押してキャッシュをクリアします。
他の人が言っているように、開発目的でキャッシュを完全に無効にすることは、コードを変更せずに簡単に行うことができます: ブラウザーの設定またはプラグインを使用します。開発の外部で、ルートベースのテンプレートの Angular テンプレート キャッシュを無効にするには、Shayan が示したように、$routeChangeStart (UI ルーターの場合は $stateChangeStart) 中にテンプレート URL をキャッシュから削除します。ただし、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 ルーターを使用している場合は、デコレーターを使用して $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 メソッドを装飾することで、同じ結果が得られると確信しています。
制御できないため、ブラウザ/プロキシのキャッシュを防止する解決策はありません。
ユーザーに新鮮なコンテンツを強制するもう 1 つの方法は、HTML ファイルの名前を変更することです! https://www.npmjs.com/package/grunt-filerevがアセットに対して行うのとまったく同じです。