AngularJS禁用了开发机器上的部分缓存

我在AngularJS中缓存部分有问题。

在我的HTML页面,我有:

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

我的偏导数被载入的地方。

当我改变HTML代码在我的部分,浏览器仍然加载旧数据。

有什么解决办法吗?

155027 次浏览

如果你谈论的是用于模板缓存而不需要重新加载整个页面的缓存,那么你可以通过如下方式清空它:

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

在标记中:

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

并按此按钮清除缓存。

在@Valentyn回答的基础上,这里有一种方法可以在ng-view内容发生变化时自动清除缓存:

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

对于开发,你也可以停用浏览器缓存-在Chrome开发工具右下角点击齿轮,并勾选选项

禁用缓存(当DevTools打开时)

更新:在Firefox中有相同的选项调试器->设置->高级部分(选中版本33)

更新2:虽然这个选项出现在Firefox一些报告,它不工作。我建议使用firebug并遵循hadaytullah的回答。

正如在其他答案中提到的,在这里在这里,缓存可以通过使用:

$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机器,但希望这仍然可以帮助到某人…

这个代码片段帮助我摆脱了模板缓存

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/ < / p >

Firefox(33.1.1)使用Firebug(22.0.6)的解决方案

  1. 工具> Web-Tools > Firebug > Firebug。
  2. 在Firebug视图中转到“Net”视图。
  3. 一个下拉菜单符号将出现在“Net”(视图的标题)旁边。
  4. 从下拉菜单中选择“禁用浏览器缓存”。

如果你正在使用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"方法来达到同样的效果。

我发布这篇文章只是为了涵盖所有的可能性,因为其他的解决方案都不适合我(他们由于角引导模板依赖而抛出错误)。

当你在开发/调试一个特定的模板时,你可以确保它总是通过在路径中包含一个时间戳来刷新,就像这样:

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

没有解决方案可以防止浏览器/代理缓存,因为您无法控制它。

另一种方式,强制新鲜内容给您的用户它重命名HTML文件!就像https://www.npmjs.com/package/grunt-filerev对资产一样。

正如其他人所说,完全出于开发目的而击败缓存可以很容易地做到,而不需要更改代码:使用浏览器设置或插件。在dev之外,要想打败Angular对基于路由的模板的模板缓存,可以在$routeChangeStart(或$stateChangeStart,对于UI Router)期间从缓存中删除模板URL,就像Shayan演示的那样。但是,这并不影响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;
}

这是Chrome的另一个选项。

点击F12打开开发人员工具。然后资源 > 缓存存储 > 刷新缓存

enter image description here

我喜欢这个选项,因为我不需要像其他答案那样禁用缓存。

我发现HTTP拦截器方法工作得很好,并允许额外的灵活性&控制。此外,您可以为每个产品版本使用一个发布散列作为buster变量来缓存bust。

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