We ran into this same issue and implemented a quick check in our interceptor to check if the item was already in the templateCache.
if ($templateCache.get(config.url)){
return config;
}
I got the idea from the cachebuster project.
Вопрос
Our application uses an $http
interceptor to add tokens to $http
requests as a form of security, the token that the interceptor adds are updated every 5 or so minutes. We now want to use ng-grid
.
However, the $http
interceptor makes is so that ng-grid
will not load the template it uses for the header row, which causes the header row to not render.
Here is the issue in action: http://plnkr.co/edit/krvBF2e4bHauQmHoa05T?p=preview
If you check the console it shows the following error:
GET http://run.plnkr.co/l0BZkZ2qCLnzBRKa/ng1389719736618headerRowTemplate.html?securityToken=123456 404 (Not Found)
The reason why this happens is because ng-grid
stores the template for the header row in the $templateCache
, and then uses an ng-include
to later retrieve it.
ng-include
uses a $http.get
request, with $templateCache
as the cache, to get the template.
The $http.get
request is intercepted by the interceptor which adds the security token to the url before it has a chance to query $templateCache
for the template using the url.
$templateCache
is expecting ng1389719736618headerRowTemplate.html
but instead gets ng1389719736618headerRowTemplate.html?securityToken=123456
The result is that the $templateCache
can't find the template, which then results in $http.get
hitting the server and getting the 404 error.
The other issue is that if we ever wanted to use $templateCache
to store templates and later retrieve it with ng-include
or $http.get
, $templateCache
would not being able to find the template because the url would get modified.
How can I get ng-grid
to display the header row with the $http
interceptor adding security tokens to the end of the urls?
here is the code Html:
<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</body>
</html>
javascript:
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
$scope.myData = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.gridOptions = { data: 'myData' };
});
app.config(function($provide, $httpProvider) {
$provide.factory('tokenAuthInterceptor', function($q){
return {
// optional method
'request': function(config) {
// do something on success
config.url = config.url + "?securityToken=123456";
return config || $q.when(config);
}
};
});
$httpProvider.interceptors.push('tokenAuthInterceptor');
});
Update
The solution that was finally decided upon was to use an angular decorator and decorate $templateCache
, the plunker was updated to reflect this.
$provide.decorator('$templateCache', function($delegate) {
var get = $delegate.get;
function formatKey(key)
{
// code for formatting keys
}
$delegate.get = function(key) {
var entry = get(key);
if (entry)
{
return entry;
}
else
{
return get(formatKey(key));
}
};
return $delegate;
});
Нет правильного решения
Другие советы
We ran into this same issue and implemented a quick check in our interceptor to check if the item was already in the templateCache.
if ($templateCache.get(config.url)){
return config;
}
I got the idea from the cachebuster project.