在发布请求后使$ resource Cache无效

inp*_*ive 18 angularjs angularjs-resource

我正在使用$ resource并缓存get请求的结果.我的问题是,在发布请求后,缓存未被无效.

以下是服务的返回值:

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

这是我在控制器中使用的保存方法.如您所见,我正在使用post请求上的回调来重新计算查询/名词列表.

var newNoun = new Noun($scope.noun);
newNoun.$save(function(x) {
  $scope.nouns = Noun.query();
});
Run Code Online (Sandbox Code Playgroud)

我想在调用post或其他非get方法后使缓存无效.我怎么能这样做?这已经内置到$ resource中了还是我需要自己实现它?

run*_*arm 29

您可以创建一个包装器服务来执行您想要的缓存,例如:

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);
  };
});
Run Code Online (Sandbox Code Playgroud)

然后更换任何$resourcecachedResource.

示例plunker: http ://plnkr.co/edit/lIQw4uogcoMpcuHTWy2U?p = preview

  • 我认为拦截器还应删除查询URL的条目,否则在保存/删除/删除条目后查询将返回旧信息. (4认同)

Jan*_*ock 5

虽然@ runTarm的答案很好,但它不允许从继承服务轻松定制操作,例如以下是不可能的:

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

在这种情况下,这个定义save将被替换为存在的定义CachedResource.

但它可以通过替换从Angular 1.4轻松修复

actions = angular.extend({}, actions, {
Run Code Online (Sandbox Code Playgroud)

actions = angular.merge({}, actions, {
Run Code Online (Sandbox Code Playgroud)

这样两个对象都是深度合并的.

更好的解决方案

在上面的场景中,CachedResource中定义的操作选项优先于继承服务中的自定义配置.要解决这个问题,请切换传递给的参数的顺序merge:

actions = angular.merge({}, { /* default options get, query, etc. */ }, actions);
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,以下内容将按预期工作(即在调用时使用DESTROY而不是默认值):DELETEremove

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