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

Men*_*ion 210 caching browser-cache angularjs

我在AngularJS中缓存部分问题.

在我的HTML页面中,我有:

<body>
 <div ng-view></div>
<body>
Run Code Online (Sandbox Code Playgroud)

我的部分加载的地方.

当我在部分更改HTML代码时,浏览器仍会加载旧数据.

有没有解决方法?

Luk*_*lar 201

对于开发,您还可以停用浏览器缓存 - 在右下角的Chrome开发工具中单击齿轮并勾选该选项

禁用缓存(当DevTools打开时)

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

更新2:虽然这个选项出现在Firefox的某些报告中但它不起作用.我建议使用firebug并跟随hadaytullah回答.

  • 这应该是公认的答案,因为它不需要代码更改,而且更符合OP的要求.当然,您需要一个生产应用程序来缓存请求,因此如果代码保留在生产应用程序中,那么执行上述人员建议的内容(虽然意义重大)可能会出现问题. (7认同)
  • 这在Firefox中不起作用.即使禁用缓存并且工具箱处于打开状态,模板仍会被缓存. (5认同)
  • 缓存是否也会影响生产?如果我将新的Web文件推送到服务器,会阻止生产客户端的后续请求加载预先发布的缓存版本,该怎么办? (4认同)

Mar*_*cok 111

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

myApp.run(function($rootScope, $templateCache) {
   $rootScope.$on('$viewContentLoaded', function() {
      $templateCache.removeAll();
   });
});
Run Code Online (Sandbox Code Playgroud)

  • 看起来很有希望,除非它不起作用. (40认同)
  • **一点警告:**清空$ templateCache实际上可能会产生意想不到的后果.例如,[UI Bootstrap](http://angular-ui.github.io/bootstrap/)在初始化期间将默认部分直接添加到$ templateCache,之后期望它们在那里. (30认同)
  • @Mukun:除了不使用removeAll()之外,我看到它的方式并不容易,但只需使用remove()删除需要清除的键.您需要某种记账才能知道要删除的密钥. (4认同)

Chr*_*ter 37

如其他答案中所述,此处此处可以使用以下命令清除缓存:

$templateCache.removeAll();
Run Code Online (Sandbox Code Playgroud)

但是正如gatoatigrado评论中所建议的那样,只有在没有任何缓存标头的情况下提供html模板时,这似乎才有效.

这对我有用:

角度:

app.run(['$templateCache', function ( $templateCache ) {
    $templateCache.removeAll(); }]);
Run Code Online (Sandbox Code Playgroud)

您可能会以各种方式添加缓存标头,但这里有一些适合我的解决方案.

如果使用IIS,请将其添加到您的web.config:

<location path="scripts/app/views">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>
Run Code Online (Sandbox Code Playgroud)

如果使用Nginx,您可以将其添加到您的配置:

location ^~ /scripts/app/views/ {
    expires -1;   
}
Run Code Online (Sandbox Code Playgroud)

编辑

我刚才意识到这个问题提到了dev机器,但希望这可能仍然有助于某人......

  • 是的,即使这不直接回答原始问题,这确实帮助我解决了在网站上的缓存问题. (2认同)

Val*_*nov 31

如果您正在讨论用于缓存模板而不重新加载整个页面的缓存,那么您可以通过以下方式清空它:

.controller('mainCtrl', function($scope, $templateCache) {
  $scope.clearCache = function() { 
    $templateCache.removeAll();
  }
});
Run Code Online (Sandbox Code Playgroud)

并在标记中:

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

然后按此按钮清除缓存.


had*_*lah 22

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

  1. 工具> Web工具> Firebug>打开Firebug.
  2. 在Firebug视图中,转到"Net"视图.
  3. "Net"旁边会出现一个下拉菜单符号(视图标题).
  4. 从下拉菜单中选择"禁用浏览器缓存".


Cod*_*ank 19

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

app.run(function($rootScope, $templateCache) {
    $rootScope.$on('$routeChangeStart', function(event, next, current) {
        if (typeof(current) !== 'undefined'){
            $templateCache.remove(current.templateUrl);
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

有关以下代码段的详细信息,请访问以下链接:http: //oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/


dio*_*ney 16

我发布这个只是为了涵盖所有可能性,因为其他解决方案都不适用于我(他们因为角度引导模板依赖性而引发错误等等).

在开发/调试特定模板时,可以通过在路径中包含时间戳来确保它始终刷新,如下所示:

       $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();
            };
          }
        });
Run Code Online (Sandbox Code Playgroud)

注意最后?nd=' + Date.now()templateUrl变量.


bra*_*w2k 11

正如其他人所说的那样,可以在不更改代码的情况下轻松完成为开发目的而完全取消缓存:使用浏览器设置或插件.在开发之外,为了击败基于路由的模板的Angular模板缓存,在$ routeChangeStart(或$ stateChangeStart,用于UI路由器)期间从缓存中删除模板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;
    }
Run Code Online (Sandbox Code Playgroud)


Ama*_*jan 8

如果您正在使用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]);
Run Code Online (Sandbox Code Playgroud)

我相信你可以通过装饰$ routeProvider中的"when"方法来获得相同的结果.