【问题标题】:Angularjs ng-include force reloadAngularjs ng-include 强制重新加载
【发布时间】:2015-12-17 17:56:38
【问题描述】:

我已阅读有关此主题的几篇文章,但在最初从远程数据服务器加载后,我仍然无法通过 ng-include 加载数据以重新加载。

(例如How to reload / refresh model data from the server programmatically?

I have a GSP page which renders a pull down menu of options, and when one is selected, ng-include calls a remote server and displays the data (in an ng-grid).因此 ng-include 需要 URL 中远程服务器的完整路径。此代码在第一次使用选项时正常工作,但不会在后续选择时重新加载数据。我知道 Angularjs 正在缓存数据,但我需要强制它重新加载。是否有一个事件可以在“myTabController”中捕获以强制它调用 ng-include?是否可以禁用缓存?由于无法将 Angularjs 中的参数传递到 ng-include 的 URL,这些参数是通过另一部分的 AJAX 调用发送的,因此数据服务器在发出 ng-include 请求之前已经拥有参数。

_myTabs.gsp

<div ng-controller= "myTabController" ng-init="init(${selIds})">
<select name="tabSelect" ng-model= "tab" ng-options="t.name for t in tabs"></select>
<form name="tabForm">
  <div ng-switch="tab.value">
    <div ng-switch-when="optionA"<div ng-include="'https://datasrv:8453/DataApp/dataCtrl/aData'" ><div></div>
    <div ng-switch-when="optionB"<div ng-include="'https://datasrv:8453/DataApp/dataCtrl/bData'" ><div></div>
    <div ng-switch-when="optionC"<div ng-include="'https://datasrv:8453/DataApp/dataCtrl/cData'" ><div></div>
  </div>
</form>
</div>

myTabs.js

angular.module('myApp', ['ui.grid', 'ui.grid.resizeColumns', 'ngAnimate', 'ngRoute']);
app.controller("myTabController", function($scope, $interval, $filter, $window, $http, $rootScope, uiGridConstants){
$scope.tabs = {
  { name: '--- Please Select an Option ---', value: ' '},
  { name: 'A Label', value: 'optionA'},
  { name: 'B Label', value: 'optionB'},
  { name: 'C Label', value: 'optionC'}
 ];
}]);

编辑: 从对我的问题的回复看来,调用 $templateCache.removeAll() 可以解决这个问题。我可以在 ng-include 中添加一个 onload="xx()",在 myTabController 中添加一个函数:

$scope.xx = function(){
  $templateCache.removeAll();
}

但它当然告诉我 $templateCache 没有定义。所以我在运行块内尝试了这个:

$scope.xx = function(){
  app.run( function( $templateCache ){  
    $templateCache.removeAll();
  });
}

这并没有产生错误,但它没有做任何事情。函数 xx() 被调用,但它没有调用 $templateCache.removeAll()。我错过了什么?


编辑 2。

我尝试使用指令生成 ng-include 标记:

    <div ng-switch-when="optionA"<div mydir ng-attr-path="https://datasrv:8453/DataApp/dataCtrl/aData" ><div></div>

在指令中,我尝试在 URL 中添加一个随机数以使其唯一:

.directive('mydir', ['$compile', function($compile){
  restrict: 'A',
  template: function( elem, attr ){
    var r = Math.random()
    var rpath = attr.path + '/?r=' + r
    return "<div ng-include=\"'" + rpath + "'\" onload=\""xx('" + rpath + "')\"></div>"; 
  }
};

不幸的是,这没有任何区别。它确实正确生成了 ng-include,包括最后的随机字符串。它显示了一次数据,但在后续调用中从未重新生成 URL。但是,每次加载时都会调用 xx() 函数。

关键是在每次选择菜单项时以某种方式强制调用此指令,因此再次调用随机数以更改 URL。或者使用 xx() 函数清除缓存。但是怎么做呢?


编辑 3: 我发现使用“{{val}}”符号将值传递到 ng-include 的 URL 中的指令存在问题。参考:modifying ng-include directive

【问题讨论】:

  • IDK 如果这回答了你的问题,但是$http 上有一个属性可以让你告诉它不要缓存某些东西。 docs.angularjs.org/api/ng/service/$http 来自上面的链接:cache – {boolean|Cache} – 如果为真,默认的 $http 缓存将用于缓存 GET 请求,否则如果使用 $cacheFactory 构建的缓存实例,此缓存将用于缓存.此外,最好将它放在一个指令中,以便对整个事情的工作方式进行更细粒度的控制,而不是使用 ng-include。
  • 谢谢,这看起来很有希望,我看到 $http 已传递到 myTabController,但我不清楚如何使用它。也许 $http.defaults.cache = false; ?我会试试的...
  • 或者根据你的要求做这样的事情:$http.get('/api/users.json', { cache: true }).success(function(data){...}).error(function(data){...}) 话虽如此,听起来你在学习 Angularjs 方面还很早。根据工作要求和其他情况,如果这只是一个个人项目,您可能需要考虑使用昨天正式放弃测试版的 Angular 2。
  • 所以只需添加 $http.defaults.cache = false;进入 myTabController 似乎没有做任何事情。请原谅我对 Angularjs 的无知,我习惯于直接使用 GSP。在这种情况下,我不确定如何使用 $http.get 。我没有提到的一件事是传递给 ng-include 的远程 URL 实际上是由 GSP 生成的。
  • 您是否尝试附加一个?以及 URL 的当前时间戳,例如 https://datasrv:8453/DataApp/dataCtrl/bData?23453453456?这有助于破坏缓存。

标签: javascript angularjs gsp


【解决方案1】:

首先,所有的 Angular html 加载后都会转到 $templateCahce,您可以手动管理它,例如:

  $templateCache.put('qwerty', 'pit is best'); 

然后

<div ng-include="'qwerty'" ></div>

您还可以使用 $templateCache.remove 从中删除任何内容。

如果您删除模板,那么 Angular 将尝试从服务器加载新的 html。 现在浏览器缓存可能会发挥作用 - 要禁用它,您可能需要在 http 拦截器中添加类似 ?timestamp= 的内容。

注意:您关于 ng-include 的陈述对我来说似乎很奇怪 - 当然您可以将参数传递给 ng-include。这就是你应该做的:

<div ng-include="myURL"> </div>

所以你先做myURL = 'https://datasrv:8453/DataApp/dataCtrl/cData/selection=1' 然后myURL = 'https://datasrv:8453/DataApp/dataCtrl/cData/selection=2' 然后你根本不应该关心缓存。

【讨论】:

  • 我没有提到传递给 ng-include 的 URL 实际上是由自定义 GSP 标签生成的,所以在 Angularjs 看到它的时候它已经在服务器端生成了。选择参数通过此菜单之外的单独 AJAX 调用传递到远程服务器。
  • 实际的 GSP 代码如下所示: 然后 GSP 自定义标签生成完整的 ng-include 代码,我示例中列出。所以我认为没有办法将 Angularjs 中的参数传递到 GSP 标记中。
  • 如何从控制器调用 $templateCache.removeAll()?我可以将 $templateCache 添加到传入的参数列表中吗?
  • $templateCache 是一个普通的服务,你可以将它注入任何控制器。如果你在服务器端生成这个 - 考虑不使用 ng-include,而是说 custom-include="url" data-custom-include="smth_here"...
  • 再次,请原谅我的无知,如何将 $templateCache 注入控制器?当我尝试将 $templateCache 添加到控制器“app.controller("myTabController", function($scope, ..., $templateCache)) 中的参数列表中时,我收到一个错误:“指令'uiGrid' 的模板必须完全一个根元素”
【解决方案2】:

使用 ng-include 加载模板后,您希望它在单击按钮或单击任何链接时重新加载:-

案例 1:- 您的模板已经加载到 DOM 中。您只需要更新与元素关联的属性。

案例 2:- 使用 $scope.$broadcast 调用映射到模板的函数。 使用 $broadcast() 您将能够更新已与 DOM 关联的模型/属性,并且您的模板将被重新加载。

【讨论】:

    猜你喜欢
    • 2015-06-05
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    相关资源
    最近更新 更多