javascriptangularjsgsp

Angularjs ng-include force reload


I have read several posts on this topic, but am still unable to get data loaded via ng-include to re-load after initially being loaded from a remote data server.

(Example 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). Thus the ng-include needs the full path to the remote server in the URL. This code works correctly the first time an option is used, but will not re-load the data on subsequent selections. I understand that Angularjs is caching the data, but I need to force it to be re-loaded. Is there an event that I can catch inside "myTabController" to force it to call the ng-include? Is it possible to disable the cache? Since it is not possible to pass arguments from Angularjs into the URL of the ng-include, these parameters are being sent via AJAX calls in another section, so that the data server already has the parameters before the ng-include request is made.

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

Edit: From the replies to my question it appears that calling $templateCache.removeAll() could solve this problem. I can add an onload="xx()" to the ng-include, and a function to myTabController:

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

but of course it tells me that $templateCache is not defined. So I tried this inside of a run block:

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

This did not generate an error, but it didn't do anything. The function xx() was being called, but it was not calling $templateCache.removeAll(). What am I missing?


Edit 2.

I tried using a directive to generate the ng-include tag:

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

In the directive, I tried adding a random number to the URL to make it unique:

.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>"; 
  }
};

Unfortunately this did not make any difference. It did generate the ng-include correctly, including the random string at the end. It displayed the data once, but the URL was never re-generated on subsequent calls. The xx() function was called every time it was loaded, however.

The key is to somehow force this directive to be called each time the menu item is selected, so the random number is called again to change the URL. Or use the xx() function to clear the cache. But how?


Edit 3: I see that there are problems with passing values using the "{{val}}" notation into a directive into the URL for an ng-include. Reference: modifying ng-include directive


Solution

  • First of all, all angular html when loaded go to $templateCahce, which you can manage manually, like:

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

    then

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

    You can also remove anything from it using $templateCache.remove.

    If you remove template, then angular will try to load new html from server. Now browser cache may come into play - to disable it you may want add something like ?timestamp= in http interceptor.

    Note: your statement about ng-include seems weird to me - of course you can pass arguments to ng-include. And that's what you should do:

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

    so u first do myURL = 'https://datasrv:8453/DataApp/dataCtrl/cData/selection=1' then myURL = 'https://datasrv:8453/DataApp/dataCtrl/cData/selection=2' and then you should not care about cache at all.