我在AngularJS中缓存局部对象时遇到问题。
在我的HTML页面中,我有:
<body>
<div ng-view></div>
<body>
我的零件加载的地方。
当我更改部分HTML代码时,浏览器仍会加载旧数据。
有什么解决方法吗?
Ctrl+Shift+R
(即硬重载)和无论什么缓存机制用于铬会忽视它再取出所有的脚本,样式等
ng-include
| ng-view
| templateUrl
通过此快捷方式都没有处理
我在AngularJS中缓存局部对象时遇到问题。
在我的HTML页面中,我有:
<body>
<div ng-view></div>
<body>
我的零件加载的地方。
当我更改部分HTML代码时,浏览器仍会加载旧数据。
有什么解决方法吗?
Ctrl+Shift+R
(即硬重载)和无论什么缓存机制用于铬会忽视它再取出所有的脚本,样式等
ng-include
| ng-view
| templateUrl
通过此快捷方式都没有处理
Answers:
对于开发,您还可以停用浏览器缓存-在右下角的Chrome开发者工具中,点击齿轮并勾选选项
禁用缓存(打开DevTools时)
更新:在Firefox中,调试器->设置->高级部分中有相同的选项(已检查版本33)
更新2:尽管此选项显示在Firefox中,但有些报告不起作用。我建议使用萤火虫并遵循hadaytullah的答案。
这是在@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
,请将其添加到您的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
机器,但希望这仍然可以对某人有所帮助...
如果您正在谈论用于缓存模板而不用于重新加载整个页面的缓存,则可以通过以下方式将其清空:
.controller('mainCtrl', function($scope, $templateCache) {
$scope.clearCache = function() {
$templateCache.removeAll();
}
});
并在标记中:
<button ng-click='clearCache()'>Clear cache</button>
然后按此按钮清除缓存。
此代码段帮助我摆脱了模板缓存
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/
if (!current) { return; }
我发布此文档只是为了涵盖所有可能性,因为其他任何解决方案都不适合我(它们因angular-bootstrap模板依赖性而引发错误)。
在开发/调试特定模板时,可以通过在路径中包含时间戳来确保它总是刷新,如下所示:
$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
变量。
.value('DEBUG', true)
以启用或禁用该行。
.run(function($rootScope) { $rootScope.DEBUG = true; ...
的指令注入$ rootScope内等,然后.directive('filter', ['$rootScope', function($rootScope)...
在返回的对象属性:templateUrl: '/app/components/filter/filter-template.html' + ($rootScope.DEBUG ? '?n=' + Date.now() : '')
。也许您可以详细说明.value('DEBUG',true)方法?已投票!
.value('DEBUG', true
与您的用法 相同$rootScope
,但不会造成混乱:)您以后可以注入DEBUG
控制器并作为常规服务进行查询。
.value(...)
如果不是太复杂,您是否可以将答案中的源代码扩展为包括小东西?我想后面的概念是我所不知道的有角度的最佳实践。
正如其他人所说,完全可以轻松实现出于开发目的的缓存,而无需更改代码:使用浏览器设置或插件。在开发人员之外,要击败基于路由的模板的Angular模板缓存,请在Shaft显示的$ routeChangeStart(或对于UI Router为$ stateChangeStart)期间从缓存中删除模板URL。但是,这不会影响ng-include加载的模板的缓存,因为这些模板不是通过路由器加载的。
我希望能够在生产环境中修复任何模板,包括由ng-include加载的模板,并使用户能够在浏览器中快速收到此修复程序,而不必重新加载整个页面。我也不担心打败HTTP缓存模板。解决方案是拦截该应用程序发出的每个HTTP请求,忽略那些不是针对我的应用程序.html模板的HTTP请求,然后向该模板的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”方法来达到相同的结果。
我发现HTTP拦截器方法工作得很好,并提供了更多的灵活性和控制力。另外,您可以通过使用发行版哈希作为无效变量来为每个生产发行版进行缓存无效化。
这是使用dev的devcachebusting方法的样子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');
}]);
没有解决方案来阻止浏览器/代理缓存,因为您无法对其进行控制。
另一种将新鲜内容强加给用户的方法是重命名HTML文件!就像https://www.npmjs.com/package/grunt-filerev一样处理资产。
app.config.update(SEND_FILE_MAX_AGE_DEFAULT=0)
我flask_app.py
。(我想其他Web服务器也存在类似的情况)。