如何在 AngularJS 中刷新/使 $resource 缓存失效

我有一个简单的 User $资源,它使用默认的 $http 缓存实现,如下所示:

factory('User', function($resource){
return $resource(endpoint + '/user/current/:projectId', {},
{get:
{
cache: true,
method: 'GET'
}
}
);
})

这种方法非常有效,例如,在应用程序中只调用服务器一次,然后从缓存中获取值。

但是在执行某个操作之后,我需要刷新服务器上的值。有什么简单的方法吗?

谢谢。

60480 次浏览

Instead of using a boolean argument in the cache property of each action you can pass on a cache instance created with $cacheFactory which you can have more control over (i.e. clear the cache).

Example usage:

app.factory('Todos', function($resource, $cacheFactory) {
var cache = $cacheFactory('todo');
return $resource(apiBaseUrl + '/todos/:id', { id: '@id' }, {
'get': { method: 'GET', cache: cache  },
'query': { method: 'GET', cache: cache, isArray: true }
});
});

Keep the boolean and get the $http cache:

var $httpDefaultCache = $cacheFactory.get('$http');

Then you can control it like any another cache made with $cacheFactory, a usage instance provided below:

$httpDefaultCache.remove(key);
// Where key is the relative URL of your resource (eg: /api/user/current/51a9020d91799f1e9b8db12f)

I came across this thread looking for something similar, but found that $resource will manage the cache for you automatically, so there's no need to force the cache to be cleared.

The idea is that if you have a resource that you can query, that query response will be cached, but if you save something for that same resource, the previously cached data must be invalid, so it is cleared for you. It makes sense that it would work this way.

Here's some code I use to do this (you can ignore the possibly odd-looking factory creation part and pay attention to the "class" body).

'use strict';


sampleApp.players.$ng.factory('sampleApp.players.PlayerService', [
'$log',
'$resource',
sampleApp.players.PlayerService = function ($log, $resource) {
var service = {};


$log.info('Creating player resource.');
var Player = $resource('/api/players', {}, {query: {
isArray: true,
cache: true,
method: 'GET'
}});


service.addPlayer = function(playerName) {
$log.info('Saving a new player.');
return new Player({name: playerName}).$save();
};


service.listPlayers = function () {
$log.info('Fetching players.');
return Player.query();
};


return service;
}]);

If you call the listPlayers function several times, the first call makes a http get request and all subsequent calls are cached. If you call addPlayer though, a http post is performed as expected, and then the next call to listPlayers will perform a http get (not cached).

This keeps you out of the business of managing someone else's ($http) cache and trying to keep up with which url's are being used for requests and which are clearing caches at the right times.

I suppose the moral of the story here is to work with the library and all will be well... except for any bugs or incomplete features, but Angular doesn't have any of those ;)

p.s. This is all running on AngularJS 1.2.0.