AngularJS禁用开发机器上的部分caching
我在AngularJS中caching部分有问题。
在我的HTML页面中,我有:
<body> <div ng-view></div> <body>
在哪里我的部分被加载。
当我更改HTML代码时,浏览器仍旧加载旧数据。
有没有解决办法?
对于开发,您也可以停用浏览器caching – 在右下angular的Chrome开发工具中点击齿轮并勾选选项
禁用caching(而DevTools处于打开状态)
更新:在Firefox中,在debugging器 – >设置 – >高级部分中有相同的选项(已针对版本33进行了检查)
更新2:虽然这个选项出现在Firefox的一些报告它不起作用。 我build议使用萤火虫,并遵循hadaytullah的答案。
在@ Valentyn的答案的基础上,有一种方法可以在ng-view内容改变的时候自动清除caching:
myApp.run(function($rootScope, $templateCache) { $rootScope.$on('$viewContentLoaded', function() { $templateCache.removeAll(); }); });
正如在其他答案中提到的, 在这里和这里 ,可以使用以下方法清除caching:
$templateCache.removeAll();
然而,正如gatoatigrado在评论中所build议的那样 ,这只有在html模板没有任何caching标题的情况下才能工作。
所以这对我有用:
angular度:
app.run(['$templateCache', function ( $templateCache ) { $templateCache.removeAll(); }]);
您可能会以各种方式添加caching标头,但这里有几个适用于我的解决scheme。
如果使用IIS
,请将此添加到您的web.config中:
<location path="scripts/app/views"> <system.webServer> <staticContent> <clientCache cacheControlMode="DisableCache" /> </staticContent> </system.webServer> </location>
如果使用Nginx,你可以将它添加到你的configuration中:
location ^~ /scripts/app/views/ { expires -1; }
编辑
我刚刚意识到这个问题提到dev
机器,但希望这可能仍然有助于某人…
如果你正在谈论caching,而不用重新加载整个页面的caching模板,那么你可以通过如下的东西来清空它:
.controller('mainCtrl', function($scope, $templateCache) { $scope.clearCache = function() { $templateCache.removeAll(); } });
在标记中:
<button ng-click='clearCache()'>Clear cache</button>
然后按此button清除caching。
解决scheme对于Firefox(33.1.1)使用Firebug(22.0.6)
- 工具> Web-Tools> Firebug>打开Firebug。
- 在Firebug视图中,转到“净”视图。
- “Net”(视图的标题)旁边将出现一个下拉菜单符号。
- 从下拉菜单中select“禁用浏览器caching”。
这段代码帮助我摆脱了模板caching
app.run(function($rootScope, $templateCache) { $rootScope.$on('$routeChangeStart', function(event, next, current) { if (typeof(current) !== 'undefined'){ $templateCache.remove(current.templateUrl); } }); });
下面的代码片段的细节可以在这个链接中find: http : //oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/
我张贴这只是为了涵盖所有的可能性,因为没有其他解决scheme为我工作(他们抛出错误angular度引导模板依赖等)。
在开发/debugging特定模板时,可以通过在path中包含时间戳来确保它始终刷新,如下所示:
$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
variables中最后的?nd=' + Date.now()
。
正如其他人所说的,为了开发目的而彻底击败caching可以在不改变代码的情况下轻松完成:使用浏览器设置或插件。 在开发之外,要打败基于路由的模板的Angular模板caching,请在Shayan展示的$ routeChangeStart(或UI state路由器的$ stateChangeStart)期间从caching中删除模板URL。 但是,这不会影响由ng-include加载的模板的caching,因为这些模板不是通过路由器加载的。
我希望能够在生产环境中修补任何模板,包括由ng-include加载的模板,并让用户可以快速在浏览器中接收修补程序,而不必重新加载整个页面。 我也不关心打败模板的HTTPcaching。 解决scheme是拦截应用程序所做的每个HTTP请求,忽略那些不适用于我的应用程序的.html模板的请求,然后向每分钟更改的模板URL添加一个参数。 请注意,path检查是特定于您的应用程序模板的path。 要获得不同的时间间隔,请更改param的math运算,或完全删除%以获取caching。
// 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服务,并将一个查询string参数附加到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”方法来获得相同的结果。
我发现HTTP拦截器方法工作得非常好,并允许额外的灵活性和控制。 此外,通过使用释放哈希作为巴斯特variables,您可以caching每个生产版本。
以下是使用Date
的dev cachebusting方法的样子。
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'); }]);
没有解决scheme来阻止浏览器/代理caching,因为您无法控制它。
另一种方式强制新鲜的内容给你的用户它重命名的HTML文件! 完全像https://www.npmjs.com/package/grunt-filerev这样做的资产。;
这是Chrome中的另一个选项。
打F12打开开发者工具。 然后资源 > 高速caching存储 > 刷新 高速 caching 。
我喜欢这个选项,因为我不必像其他答案那样禁用caching。
每30秒刷新一次文档:
<head> <meta http-equiv="refresh" content="30"> </head>
w3schools HTML http-equiv属性