强制重新加载指令模板

33

我正在开发一个使用多个指令的AngularJS应用。这些指令的模板存储在一个单独的html文件中。在编辑这些模板时,我的浏览器在重新加载后无法检测到任何更改,并且始终使用缓存版本。源代码的任何其他更改都会被检测到并导致重新加载。

我猜问题有点类似于$templateCache,这似乎是AngularJS在加载模板时使用的。

在AngularJS 1.0.2的源代码中,我在compileTemplateUrl()的第4317行找到了以下内容:

$http.get(origAsyncDirective.templateUrl, {cache: $templateCache})

我想知道是否还有其他人遇到过这种问题,以及是否有一种方法可以告诉AngularJS何时进行缓存以及何时不进行缓存。

3个回答

40

我知道这是一个老问题,但这里有一个更简单的解决方法,虽然有点hacky,但对我有效,并且不需要对$templateCache进行任何操作。

每当我遇到这个问题(我在指令模板中看到它,但也在静态JSON文件中看到),我会在加载的URL末尾添加一个查询参数,像这样:

...
templateUrl: "partials/template.html?1",
...
无论何时我对模板进行更改,如果它没有重新加载,我就在末尾增加那个数字。由于浏览器不知道这可能意味着服务器上的特殊含义,它应该尝试重新加载已更改的URL,无论它是否被缓存。这也将确保文件在生产环境中重新加载。

每当我对模板进行更改时,如果没有重新加载,我都会在末尾增加一个数字。由于浏览器不知道这可能对服务器有什么特殊含义,所以它应该尝试重新加载已更改的URL,无论它是否被缓存。这也可以确保在生产环境中重新加载该文件。


7
如果您有许多模板可以使用,您可以使用变量var v = "1"; $routeProvider.when('/', {templateUrl: '/pages/home.html?v=' + v, controller: 'HomeCtlr'}); - dpineda
1
"partials/template.html?" + Date.now() 对我来说完美运作。 - mhodges

15

作为一款JavaScript应用程序,模板缓存存储在您的浏览器中。您实际上可以手动填充$cache或停止浏览器缓存模板(因为对于生产而言,缓存不会是一个问题),使用开发者工具。

要强制填充缓存:

function Main($cache) {
    $cache.data['first.html'] = {value: 'First template'};
    $cache.data['second.html'] = {value: '<b>Second</b> template'};

}

Main.$inject = ['$xhr.cache'];​

这个示例中可以看到它的工作原理。

为了防止浏览器缓存模板(引自Google Groups中的一个帖子,正是关于这个问题):

我和我的团队也遇到过这个问题。我们在使用Chrome进行开发时的解决方案是:打开开发者工具,选择右下角的齿轮图标,然后选择“Network” - “Disable cache”。

这解决了我们所有部分/模板缓存问题。


14
在我的本地Chrome版本中禁用缓存并不能真正解决我的问题,因为作为用户浏览网站的人仍会加载缓存版本。 - F Lekschas
2
强制缓存每次重新加载模板对我来说看起来像是一种hack。但我想我别无选择。在我的本地Chrome版本中禁用缓存只能解决我的问题。浏览网站的其他访问者仍然会加载缓存版本。因此,在生产模式下进行的更新直到用户清除其缓存才可见。 - F Lekschas
我在我的AngularJS项目中使用Yeoman,因此部署的文件名都有哈希前缀。这使得缓存不是一个真正的问题,因为对应用程序进行任何基本更改时都会立即识别(文件名不同)。对于测试,我也使用Yeoman,并且它强制重新加载所有资产。 - Tiago Roldão
我想尝试一下Yeoman,但迄今为止还没有时间。也许现在是时候去尝试一下了 :) - F Lekschas

1
app.controller('someCtrl', function ($scope, $cacheFactory, templateRequest)
{   
    $scope.refreshTemplate = function ()
    {
      var tpl = "<template name>";
      $cacheFactory.get('templates').remove(tpl);
      $templateRequest(tpl).then(function ok(){
          console.log("Template "+tpl+" loaded.");
      });
     }
   ...
  }

当您调用refreshTemplate函数时,会导致重新加载。

我不知道为什么这个答案没有被采纳...它的功能和预期一样... - Scriptlabs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接