42

在 http 中添加缓存非常简单。(通过传递 cache=true )

http://docs.angularjs.org/api/ng.$http有缓存选项。

如何在 angularjs 的 $resource 中添加类似的功能?

4

8 回答 8

59

从 1.1.2 ( commit ) 开始,所有 $httpConfig 选项都直接暴露在 $resource 操作对象中:

return {
  Things: $resource('url/to/:thing', {}, {
    list : {
      method : 'GET',
      cache : true
    }
  })
 };
于 2013-04-18T10:08:53.843 回答
56

在 AngularJs 中实现自己的缓存非常容易。只需使用$cacheFactory

app.factory('myService', function($resource, $cacheFactory) {
   var cache = $cacheFactory('myService');
   var User = $resource('/user/:userId', {userId:'@id'});

   return {
      getResource: function(userId) {
         var user = cache.get(userId);
         if (!user) {
            user = User.get({userId:userId});
            cache.put(userId, user);   
         }
         return user;
      }
   };
});
于 2012-12-30T21:13:18.953 回答
24

正如文档所述,$resource内置了对$cacheFactory的支持。您可以通过cache每个操作的属性将其传递:

cache{boolean|Cache}– 如果true,则使用默认$http缓存来缓存GET请求,否则如果使用 构建缓存实例$cacheFactory,则使用该缓存进行缓存。

示例用法:

app.factory('Todos', function($resource, $cacheFactory) {
    var todosCache = $cacheFactory('Todos');
    return $resource(apiBaseUrl + '/todos/:id', {id: '@id'}, {
        'get': { method:'GET', cache: todosCache},
        'query': { method:'GET', cache: todosCache, isArray:true }
    });
});
于 2014-03-17T22:52:37.323 回答
6

这似乎没有在这里提到,但您也可以覆盖默认方法。

app.factory("List", ["$resource", function($resource) {
    return $resource("./lists/:path/:action.json", {}, {
        get: {
            method: "GET",
            cache: true
        }
    });
}]);
于 2014-01-16T03:18:56.487 回答
6

您还可以为 $http 设置默认缓存,从而为基于它的 $resource 设置默认缓存。

我的设置具有出色的角度缓存,允许 LocalStorage 并符合 $cacheFactory:

app.run(function($http, DSCacheFactory) {

    DSCacheFactory('defaultCache', {
        deleteOnExpire: 'aggressive',
        storageMode: 'localStorage' 
    });

    $http.defaults.cache = DSCacheFactory.get('defaultCache');
});
于 2014-04-15T12:33:05.433 回答
0

查看 angular-resource 源表明以当前编写的方式无法触发缓存。

这是来自源的请求对象:

$http({
    method: action.method,
    url: route.url(extend({}, extractParams(data), action.params || {}, params)),
    data: data
 }).then(...)

有一些潜在的方法可以解决这个问题。

首先,您可以使用客户端持久性在本地缓存。我使用带有包装器的amplify.store(b/c 我不太喜欢 API 语法)。根据您要查找的内容以及您的目标浏览器,还有多种其他存储解决方案。也有不少人使用草坪椅

然后,您可以在本地对模型进行字符串化和存储,并根据您想要的任何规则或时间限制对其进行更新。

另一种解决方案是简单地修改角度资源以接受您正在寻找的参数。这可以很简单(只需向 $resource 添加一个附加参数)或复杂到您需要的程度。

例如

function ResourceFactory(url, paramDefaults, actions, cache) {
   ...
   var cache = cache != null ? cache : false; // Set default to false
   $http({
        method: action.method,
        url: route.url(extend({}, extractParams(data), action.params || {}, params)),
        data: data,
        cache: cache
    }).then(...)       
}

最后,根据您的要求,使用 angular.factory 创建服务可能更容易创建自己的资源。ngResource 的优点之一是在转换参数时所有的字符串插值都为您工作。但是,如果需要,您当然可以使用此逻辑进行解析,或者根据您使用的模型编写自己的逻辑。

于 2012-11-09T08:05:46.660 回答
0

我刚刚遇到了这个经过深思熟虑的模块,称为 angular-cached-resource,它将为您完成这项工作。https://github.com/goodeggs/angular-cached-resource

它是 $resource 的替代品,增加了使用 localStorage 进行缓存管理的功能。如果您的浏览器不支持本地存储,您将不会获得任何缓存优势。这是一个如何使用它的示例:

使用 $resource 的旧方法:

var Entry = $resource('/entries/:slug', {slug: '@slug'});

var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';

announcement.$save(function() {
  alert('Saved announcement.');
});

使用 $cachedResource 的新方法:

var Entry = $cachedResource('entries', '/entries/:slug', {slug: '@slug'});

var announcement = new Entry();
announcement.slug = 'announcing-angular-cached-resource';
announcement.title = 'Announcing Angular Cached Resource';
announcement.body = 'Here is why Angular Cached Resource is awesome!';

announcement.$save(function() {
  alert('Saved announcement.');
});

代码中的唯一区别是:

  1. 使用 $cachedResource 而不是 $resource
  2. 提供一个“密钥”(entries在上面的示例中),以便您即使在页面刷新或重新加载之间也可以引用它。这些条目一直存在,因为它使用 localStorage 开箱即用。

此处提供详细教程:https ://github.com/goodeggs/bites/blob/master/src/documents/open_source/2014-04-24-angular-cached-resource.md

另请注意,Angular 2.0 可能支持开箱即用的内容:https ://docs.google.com/document/d/1DMacL7iwjSMPP0ytZfugpU4v0PWUK0BT6lhyaVEmlBQ/edit

于 2015-06-10T03:13:53.273 回答
0

我正在使用 angular-resource 1.5.5 并按以下方式设置我的代码:

概括

action设置为query,并且由于 "query" 动作期望将响应反序列化为数组,因此需要将 isArray 显式设置为 true。我的理解是默认情况下 ngResource 操作期望除查询之外的对象。 看这里

控制器

angular.module("app")
    .controller('myCtrl',['$scope','myService',function($scope, myService) {
        $scope.myData= myService.myResource.query();
    }]);

服务

angular.module('app')
    .factory('myService',['$resource',function($resource){
        var baseUrl = 'http://www.MyExample.com/';
        return{
            myResource:$resource(baseURL + '/myEndpoint/:id', {id:'@id'},{
                'query':{
                    method:'GET',
                    cache:'true',
                    isArray:true
                }}),
        }
    }]);
于 2016-05-19T20:06:48.533 回答