【问题标题】:angularjs: how to add caching to resource object?angularjs:如何向资源对象添加缓存?
【发布时间】:2018-02-16 01:38:29
【问题描述】:

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

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

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

【问题讨论】:

标签: javascript angularjs


【解决方案1】:

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

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

【讨论】:

  • 也许你可以打开一个新问题并提供一个例子?
  • 这不是一个很好的答案。 AngularJS 的当前稳定版本是 1.0.7,并且有一些工作场所使用旧版本。如果我们不使用 1.1.2,我们如何解决这个问题?
  • 您可以从 $resource 文件(它不是核心的一部分)中提取相关更改,并将其修补到稳定分支中。由于 1.1.x 分支在我的经验中非常稳定,我可以推荐使用它。无论如何,这是解决问题的一种可能方法,而不是确定的答案。
【解决方案2】:

在 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;
      }
   };
});

【讨论】:

  • 其实 $resource 现在已经内置了缓存支持。无需继续手动操作。
【解决方案3】:

正如文档所述,$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 }
    });
});

【讨论】:

  • 你应该传递一个 Cache 实例(用 $cacheFactory 构建)而不是 $cacheFactory 本身。
【解决方案4】:

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

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

【讨论】:

  • cache: true 的问题在于它只缓存 GET 请求。如果你想缓存 HEAD 请求,那你就不走运了。
【解决方案5】:

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

我的设置与出色的 angular-cache 允许 LocalStorage 并符合 $cacheFactory:

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

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

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

【讨论】:

    【解决方案6】:

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

    这是来自源的请求对象:

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

    有几种可能的方法来处理这个问题。

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

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

    另一种解决方案是简单地修改角度资源以接受您正在寻找的参数。这可以很简单(只需向 $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 的优点之一是在转换参数时所有的字符串插值都为您工作。但是,如果需要,您当然可以使用此逻辑进行解析,或者根据您使用的模型编写自己的逻辑。

    【讨论】:

    • jsstorage 怎么样,你会用它来对付 amplify.store 吗?
    • 没试过,但是看语法和功能集,比Amplify更喜欢。我已经有一段时间没有看过这些了,因为我最近没有为旧浏览器编写代码(因此只使用了轻量级的 localStorage 包装器)。
    【解决方案7】:

    我刚刚遇到了这个经过深思熟虑的模块,称为 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

    【讨论】:

      【解决方案8】:

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

      总结

      action 设置为 query,并且由于“query”操作需要反序列化为数组的响应,因此需要将 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
                      }}),
              }
          }]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-16
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 2013-01-28
        • 1970-01-01
        • 2014-05-02
        相关资源
        最近更新 更多