angularjs:如何向资源对象添加缓存?

时间:2012-09-01 06:31:50

标签: javascript angularjs

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

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

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

8 个答案:

答案 0 :(得分:59)

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

return {
  Things: $resource('url/to/:thing', {}, {
    list : {
      method : 'GET',
      cache : true
    }
  })
 };

答案 1 :(得分: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;
      }
   };
});

答案 2 :(得分: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 }
    });
});

答案 3 :(得分:6)

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

app.factory("List", ["$resource", function($resource) {
    return $resource("./lists/:path/:action.json", {}, {
        get: {
            method: "GET",
            cache: true
        }
    });
}]);

答案 4 :(得分:6)

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

我的设置使用优秀的angular-cache允许LocalStorage并符合$ cacheFactory:

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

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

    $http.defaults.cache = DSCacheFactory.get('defaultCache');
});

答案 5 :(得分:0)

查看角度资源源表明,当前编写的方式无法触发缓存。

以下是来自源的请求对象:

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

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

首先,您可以使用客户端持久性在本地缓存。我使用amplify.store和包装器(b / c我真的不喜欢API语法)。根据您的需求以及您的定位浏览器,还有其他各种存储解决方案。很多人也使用lawnchair

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

另一种解决方案是简单地修改角度资源以接受您正在寻找的参数。这可能很简单(只需在$ resource中添加一个额外的参数)或复杂,因为你需要它。

e.g。

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的一个优点是,在翻译参数时,所有字符串插值都适用于您。但是,如果您需要解析,您当然可以使用此逻辑进行解析,或者根据您正在使用的模型编写自己的逻辑。

答案 6 :(得分: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。
  3. 详细教程可在此处获取: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

答案 7 :(得分:0)

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

摘要

操作设置为查询,并且由于“查询”操作期望将反序列化为数组,因此需要将isArray显式设置为true。我的理解是默认情况下ngResource操作期望除查询之外的对象。 See here

<强>控制器

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
                }}),
        }
    }]);