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

时间:2021-05-19 03:49:45

I have problem with caching partials in AngularJS.

我对AngularJS中的缓存部分有问题。

In my HTML page I have:

在我的HTML页面中,我有:

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

where my partials are loaded.

加载我的泛音。

When I change HTML code in my partial, browser still load old data.

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

Is there any workaround?

有什么解决方法吗?

13 个解决方案

#1


198  

For Development you can also deactivate the browser cache - In Chrome Dev Tools on the bottom right click on the gear and tick the option

对于开发,您还可以禁用浏览器缓存——在Chrome开发工具中,在工具栏的右下角单击并勾选选项

Disable cache (while DevTools is open)

禁用缓存(虽然DevTools打开)

Update: In Firefox there is the same option in Debugger -> Settings -> Advanced Section (checked for Version 33)

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

Update 2: Although this option appears in Firefox some report it doesn't work. I suggest using firebug and following hadaytullah answer.

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

#2


111  

Building on @Valentyn's answer a bit, here's one way to always automatically clear the cache whenever the ng-view content changes:

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

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

#3


37  

As mentioned in the other answers, here and here, the cache can be cleared by using:

如其他答案所述,这里和这里可以使用以下方法清除缓存:

$templateCache.removeAll();

However as suggested by gatoatigrado in the comment, this only appears to work if the html template was served without any cache headers.

但是,正如注释中gatoatigrado所建议的,只有在html模板没有任何缓存头的情况下,这才会有效。

So this works for me:

这工作对我来说:

In angular:

角:

app.run(['$templateCache', function ( $templateCache ) {
    $templateCache.removeAll(); }]);

You may be adding cache headers in a variety of ways but here are a couple of solutions that work for me.

你可能会添加缓存头以多种方式但以下几个解决方案,为我工作。

If using IIS, add this to your web.config:

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

<location path="scripts/app/views">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>

If using Nginx, you can add this to your config:

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

location ^~ /scripts/app/views/ {
    expires -1;   
}

Edit

编辑

I just realised that the question mentioned dev machine but hopefully this may still help somebody...

我刚刚意识到这个问题提到了开发机器,但希望这仍然可以帮助某人……

#4


31  

If you are talking about cache that is been used for caching of templates without reloading whole page, then you can empty it by something like:

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

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

And in markup:

和标记:

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

<按钮ng-click = ' clearcache()> 清楚缓存< /按钮>

And press this button to clear cache.

然后按下这个按钮清除缓存。

#5


23  

Solution For Firefox (33.1.1) using Firebug (22.0.6)

  1. Tools > Web-Tools > Firebug > Open Firebug.
  2. 工具> web工具> Firebug >打开Firebug。
  3. In the Firebug views go to the "Net" view.
  4. 在Firebug视图中,转到“Net”视图。
  5. A drop down menu symbol will appear next to "Net" (title of the view).
  6. 下拉菜单符号将出现在“Net”(视图标题)旁边。
  7. Select "Disable Browser Cache" from the drop down menu.
  8. 从下拉菜单中选择“禁用浏览器缓存”。

#6


19  

This snippet helped me in getting rid of template caching

这个片段让我摆脱模板缓存

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

The details of following snippet can be found on this link: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/

以下代码片段的详细信息可以在这个链接中找到:http://oncodesign.io/2014/02/19/safely- template- cache -in angularjs/

#7


16  

I'm posting this just to cover all possibilities since neither of the other solutions worked for me (they threw errors due angular-bootstrap template dependencies, among others).

我发布这篇文章只是为了涵盖所有的可能性,因为其他两种解决方案对我都不起作用(它们抛出了由于angular-bootstrap模板依赖等原因造成的错误)。

While you are developing/debugging a specific template, you can ensure it always refreshes by included a timestamp in the path, like this:

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

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

Note the final ?nd=' + Date.now() in the templateUrl variable.

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

#8


11  

As others have said, defeating caching completely for dev purposes can be done easily without changing code: use a browser setting or a plugin. Outside of dev, to defeat Angular template caching of route-based templates, remove the template URL from the cache during $routeChangeStart (or $stateChangeStart, for UI Router) as Shayan showed. However, that does NOT affect the caching of templates loaded by ng-include, because those templates are not loaded through the router.

正如其他人所说,为了开发目的而完全破坏缓存可以很容易地完成,而无需更改代码:使用浏览器设置或插件。在dev之外,为了击败基于路由的模板的角模板缓存,如Shayan所示,在$routeChangeStart(或$stateChangeStart)期间从缓存中删除模板URL。但是,这并不影响ng-include加载的模板的缓存,因为这些模板不是通过路由器加载的。

I wanted to be able to hotfix any template, including those loaded by ng-include, in production and have users receive the hotfix in their browser quickly, without having to reload the entire page. I'm also not concerned about defeating HTTP caching for templates. The solution is to intercept every HTTP request that the app makes, ignore those that are not for my app's .html templates, then add a param to the template's URL that changes every minute. Note that the path-checking is specific to the path of your app's templates. To get a different interval, change the math for the param, or remove the % completely to get no caching.

我希望能够在产品中热修复任何模板,包括ng-include加载的模板,并让用户在浏览器中快速接收热修复,而无需重新加载整个页面。我也不担心会破坏模板的HTTP缓存。解决方案是拦截应用程序发出的每个HTTP请求,忽略不属于我的应用程序的.html模板的请求,然后向模板的URL添加一个param,该URL每分钟都会改变。注意,路径检查是特定于应用程序模板的路径的。要获得一个不同的间隔,可以更改param的数学,或者完全删除%以获得不缓存。

// 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;
    }

#9


7  

If you are using UI router then you can use a decorator and update $templateFactory service and append a query string parameter to templateUrl, and the browser will always load the new template from the server.

如果您正在使用UI router,那么您可以使用decorator并更新$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]);

I am sure you can achieve the same result by decorating the "when" method in $routeProvider.

我相信您可以通过在$routeProvider中修饰“when”方法来达到同样的效果。

#10


3  

I found that the HTTP interceptor method works pretty nicely, and allows additional flexibility & control. Additionally, you can cache-bust for each production release by using a release hash as the buster variable.

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

Here is what the dev cachebusting method looks like using Date.

下面是使用Date的dev缓存分解方法。

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

#11


1  

Here is another option in Chrome.

这是Chrome的另一个选择。

Hit F12 to open developer tools. Then Resources > Cache Storage > Refresh Caches.

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

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

I like this option because I don't have to disable cache as in other answers.

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

#12


0  

There is no solution to prevent browser/proxy caching since you cannot have the control on it.

由于无法控制浏览器/代理缓存,所以没有解决方案。

The other way to force fresh content to your users it to rename the HTML file! Exactly like https://www.npmjs.com/package/grunt-filerev does for assets.

另一种方法是强迫用户重新命名HTML文件!就像https://www.npmjs.com/package/grunt-filerev对资产所做的一样。

#13


-3  

Refresh document every 30 seconds:

刷新文档每30秒:

<head>
  <meta http-equiv="refresh" content="30">
</head>

w3schools HTML http-equiv Attribute

w3schools HTML http-equiv属性

#1


198  

For Development you can also deactivate the browser cache - In Chrome Dev Tools on the bottom right click on the gear and tick the option

对于开发,您还可以禁用浏览器缓存——在Chrome开发工具中,在工具栏的右下角单击并勾选选项

Disable cache (while DevTools is open)

禁用缓存(虽然DevTools打开)

Update: In Firefox there is the same option in Debugger -> Settings -> Advanced Section (checked for Version 33)

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

Update 2: Although this option appears in Firefox some report it doesn't work. I suggest using firebug and following hadaytullah answer.

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

#2


111  

Building on @Valentyn's answer a bit, here's one way to always automatically clear the cache whenever the ng-view content changes:

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

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

#3


37  

As mentioned in the other answers, here and here, the cache can be cleared by using:

如其他答案所述,这里和这里可以使用以下方法清除缓存:

$templateCache.removeAll();

However as suggested by gatoatigrado in the comment, this only appears to work if the html template was served without any cache headers.

但是,正如注释中gatoatigrado所建议的,只有在html模板没有任何缓存头的情况下,这才会有效。

So this works for me:

这工作对我来说:

In angular:

角:

app.run(['$templateCache', function ( $templateCache ) {
    $templateCache.removeAll(); }]);

You may be adding cache headers in a variety of ways but here are a couple of solutions that work for me.

你可能会添加缓存头以多种方式但以下几个解决方案,为我工作。

If using IIS, add this to your web.config:

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

<location path="scripts/app/views">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>

If using Nginx, you can add this to your config:

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

location ^~ /scripts/app/views/ {
    expires -1;   
}

Edit

编辑

I just realised that the question mentioned dev machine but hopefully this may still help somebody...

我刚刚意识到这个问题提到了开发机器,但希望这仍然可以帮助某人……

#4


31  

If you are talking about cache that is been used for caching of templates without reloading whole page, then you can empty it by something like:

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

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

And in markup:

和标记:

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

<按钮ng-click = ' clearcache()> 清楚缓存< /按钮>

And press this button to clear cache.

然后按下这个按钮清除缓存。

#5


23  

Solution For Firefox (33.1.1) using Firebug (22.0.6)

  1. Tools > Web-Tools > Firebug > Open Firebug.
  2. 工具> web工具> Firebug >打开Firebug。
  3. In the Firebug views go to the "Net" view.
  4. 在Firebug视图中,转到“Net”视图。
  5. A drop down menu symbol will appear next to "Net" (title of the view).
  6. 下拉菜单符号将出现在“Net”(视图标题)旁边。
  7. Select "Disable Browser Cache" from the drop down menu.
  8. 从下拉菜单中选择“禁用浏览器缓存”。

#6


19  

This snippet helped me in getting rid of template caching

这个片段让我摆脱模板缓存

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

The details of following snippet can be found on this link: http://oncodesign.io/2014/02/19/safely-prevent-template-caching-in-angularjs/

以下代码片段的详细信息可以在这个链接中找到:http://oncodesign.io/2014/02/19/safely- template- cache -in angularjs/

#7


16  

I'm posting this just to cover all possibilities since neither of the other solutions worked for me (they threw errors due angular-bootstrap template dependencies, among others).

我发布这篇文章只是为了涵盖所有的可能性,因为其他两种解决方案对我都不起作用(它们抛出了由于angular-bootstrap模板依赖等原因造成的错误)。

While you are developing/debugging a specific template, you can ensure it always refreshes by included a timestamp in the path, like this:

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

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

Note the final ?nd=' + Date.now() in the templateUrl variable.

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

#8


11  

As others have said, defeating caching completely for dev purposes can be done easily without changing code: use a browser setting or a plugin. Outside of dev, to defeat Angular template caching of route-based templates, remove the template URL from the cache during $routeChangeStart (or $stateChangeStart, for UI Router) as Shayan showed. However, that does NOT affect the caching of templates loaded by ng-include, because those templates are not loaded through the router.

正如其他人所说,为了开发目的而完全破坏缓存可以很容易地完成,而无需更改代码:使用浏览器设置或插件。在dev之外,为了击败基于路由的模板的角模板缓存,如Shayan所示,在$routeChangeStart(或$stateChangeStart)期间从缓存中删除模板URL。但是,这并不影响ng-include加载的模板的缓存,因为这些模板不是通过路由器加载的。

I wanted to be able to hotfix any template, including those loaded by ng-include, in production and have users receive the hotfix in their browser quickly, without having to reload the entire page. I'm also not concerned about defeating HTTP caching for templates. The solution is to intercept every HTTP request that the app makes, ignore those that are not for my app's .html templates, then add a param to the template's URL that changes every minute. Note that the path-checking is specific to the path of your app's templates. To get a different interval, change the math for the param, or remove the % completely to get no caching.

我希望能够在产品中热修复任何模板,包括ng-include加载的模板,并让用户在浏览器中快速接收热修复,而无需重新加载整个页面。我也不担心会破坏模板的HTTP缓存。解决方案是拦截应用程序发出的每个HTTP请求,忽略不属于我的应用程序的.html模板的请求,然后向模板的URL添加一个param,该URL每分钟都会改变。注意,路径检查是特定于应用程序模板的路径的。要获得一个不同的间隔,可以更改param的数学,或者完全删除%以获得不缓存。

// 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;
    }

#9


7  

If you are using UI router then you can use a decorator and update $templateFactory service and append a query string parameter to templateUrl, and the browser will always load the new template from the server.

如果您正在使用UI router,那么您可以使用decorator并更新$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]);

I am sure you can achieve the same result by decorating the "when" method in $routeProvider.

我相信您可以通过在$routeProvider中修饰“when”方法来达到同样的效果。

#10


3  

I found that the HTTP interceptor method works pretty nicely, and allows additional flexibility & control. Additionally, you can cache-bust for each production release by using a release hash as the buster variable.

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

Here is what the dev cachebusting method looks like using Date.

下面是使用Date的dev缓存分解方法。

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

#11


1  

Here is another option in Chrome.

这是Chrome的另一个选择。

Hit F12 to open developer tools. Then Resources > Cache Storage > Refresh Caches.

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

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

I like this option because I don't have to disable cache as in other answers.

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

#12


0  

There is no solution to prevent browser/proxy caching since you cannot have the control on it.

由于无法控制浏览器/代理缓存,所以没有解决方案。

The other way to force fresh content to your users it to rename the HTML file! Exactly like https://www.npmjs.com/package/grunt-filerev does for assets.

另一种方法是强迫用户重新命名HTML文件!就像https://www.npmjs.com/package/grunt-filerev对资产所做的一样。

#13


-3  

Refresh document every 30 seconds:

刷新文档每30秒:

<head>
  <meta http-equiv="refresh" content="30">
</head>

w3schools HTML http-equiv Attribute

w3schools HTML http-equiv属性