Недействительный кеш $resource после отправки запроса

Я использую $resource и кэширую результаты запросов на получение. Моя проблема заключается в том, что после почтовых запросов кеш не отменяется.

Вот возвращаемое значение из службы:

return $resource('http://url.com/api/url/:id', {}, {
'query' : {
      method : 'GET',
      isArray:true,
      cache : true
    },
'get' : {
  method : 'GET',
  cache : false
}  
})

Вот метод сохранения, который я использую внутри своего контроллера. Как вы можете видеть, я использую обратный вызов в почтовом запросе для пересчета запроса/списка существительных.

var newNoun = new Noun($scope.noun);
newNoun.$save(function(x) {
  $scope.nouns = Noun.query();
});

Я хотел бы аннулировать кеш после вызова сообщения или другого метода не-get. Как я могу это сделать? Является ли это уже встроенным в $resource или мне нужно реализовать его самостоятельно?

Ответ 1

Вы можете создать службу-оболочку для выполнения кэширования, как вы хотите, например:

app.factory('cachedResource', function ($resource, $cacheFactory) {
  var cache = $cacheFactory('resourceCache');

  var interceptor = {
    response: function (response) {
      cache.remove(response.config.url);
      console.log('cache removed', response.config.url);
      return response;
    }
  };

  return function (url, paramDefaults, actions, options) {
    actions = angular.extend({}, actions, {
      'get':    { method: 'GET', cache: cache },
      'query':  { method: 'GET', cache: cache, isArray: true },
      'save':   { method: 'POST', interceptor: interceptor },
      'remove': { method: 'DELETE', interceptor: interceptor },
      'delete': { method: 'DELETE', interceptor: interceptor },
    });

    return $resource(url, paramDefaults, actions, options);
  };
});

Затем замените любой $resource на cachedResource.

Пример plunker: http://plnkr.co/edit/lIQw4uogcoMpcuHTWy2U?p=preview

Ответ 2

В то время как ответ @runTarm выше, он не позволяет легко настраивать действия из службы наследования, например. следующее было бы невозможно:

app.factory('Steps', function (CachedResource) {
    return CachedResource('/steps/:stepId', {}, {
        save: { method: 'POST', params: { stepId: '@stepId' } }
    });
});

В этом случае это определение save будет заменено на то, что представлено в CachedResource.

Решение

Но его можно легко устранить из Angular 1.4, заменив

actions = angular.extend({}, actions, {

с

actions = angular.merge({}, actions, {

чтобы оба объекта были глубоко объединены.

Еще лучшее решение

В приведенном выше сценарии варианты действий, определенные в CachedResource, были бы предпочтительнее, чем настраиваемая конфигурация при наследовании служб. Чтобы исправить это, переключите порядок аргументов, переданных в merge:

actions = angular.merge({}, { /* default options get, query, etc. */ }, actions);

С помощью этого решения, как ожидается, будет работать как ожидается (т.е. использовать DESTROY вместо стандартного DELETE при вызове remove):

app.factory('Steps', function (CachedResource) {
    return CachedResource('/steps/:stepId', {}, {
        remove: { method: 'DESTROY' }
    });
}); 

Ответ 3

$resource использует кеш по умолчанию для $http.

Вы можете получить к нему доступ, используя: $cacheFactory.get('$http')

Вы можете удалить пару значений ключа, используя метод возвращаемых кешей remove({string} key).


например:.

var key = '...the key you want to remove, e.g. `/nouns/5`...';
$cacheFactory.get('$http').remove(key);