如何使用AngularJS填充$ http $缓存

时间:2015-01-13 01:35:43

标签: angularjs

当用户登录我网站的主页面时,我通常会在主页上加载相当多的数据。比他们来到页面上的特定网址时更多。当他们点击ome页面时,这实际上填满了我在点击特定页面时单独获取的大部分数据的数据请求。

我喜欢$ http模块如何与$ cache一起工作,我想使用我的主页命中的知识来填充我知道单个页面将进行的调用缓存。

也就是说,例如,我的主页调用/ rest / clients返回所有客户端,而单个页面调用/ rest / client / 101。我想要做的是,如果首先调用/ rest / clients,那么当调用/ rest / client / 101时,不必进行新的xhr调用,但可以从缓存中获取数据if / rest / client / 101已被调用。

我之前从未做过装饰,但我想也许是$ http服务的装饰师?我查看了$ http代码,看起来缓存存储在实际的http调用的闭包中,除了下一个Get之外没有公开。

有没有人这样或类似?我找不到。任何特定的伪编码建议都会非常受欢迎。

3 个答案:

答案 0 :(得分:2)

在您的数据服务中,您有两种方法,getAll和getOne。

在服务中定义对getAll结果承诺的引用。

然后在你的getOne服务中检查是否存在该承诺,以及它是否确实使用它来过滤掉满足你的getOne需要所需的一个项目。

module.service('dataService', function($http){
  var getAllPromise = null;

  this.getAll = function(){
    if (getAllPromise !== null){
      getAllPromise;
    }

    getAllPromise = $http.get('clients');
    return getAllPromise
  };

  this.getOne = function(id){
    if (getAllPromise !== null){
      return getAllPromise
        .then(function(allData){
          //logic here to find the one in the full result set
          return theFoundItem;
        };
    }

    return $http.get('clients/' + id);
  };
});

答案 1 :(得分:1)

我找到了我要求的解决方案,但实施并使其可测试证明超出了我的技能。我将使用@brocco解决方案,但对于永久性记录,我将实际答案留给我所要求的。我没有将此标记为正确的解决方案,因为@brocco解决方案更适合我的实际问题。所以,谢谢@brocco的帮助。

您可以在下面看到我基本上做的是使用$ cacheFactory创建自己的$ cache。然后我使用新缓存对象的.put方法来填充我的缓存。然后,对client / 1 url的后续调用将获得缓存记录,而无需在实时中调用cache / 1。缓存在第一次大调用的for循环中加载。

感谢大家对此的投入。

    var myApp = angular.module('myApp', []);

    myApp.factory('speakersCache', function($cacheFactory) {
        return $cacheFactory('speakersCacheData');
    });


    myApp.controller('personController', ['$scope','$http','speakersCache', function ($scope,$http,speakersCache) {

        $scope.getAllSpeakers = function() {

            $http.get('speakers.json',{cache: speakersCache}).
                success(function (data, status, headers, config) {

                    debugger;
                    var i;
                    for(i=0;i<data.length;i++) {
                        var url = 'speaker/' + i;
                        speakersCache.put(url, data[i]);
                    }
                }).
                error(function (data, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                });
        };

        $scope.getAllSessions = function() {

            $http.get('sessions.json',{cache: speakersCache}).
                success(function (data, status, headers, config) {
                    debugger;

                }).
                error(function (data, status, headers, config) {
                    // called asynchronously if an error occurs
                    // or server returns response with an error status.
                });
        };

        $scope.getOneSpeaker = function() {
            $http.get('speaker/1',{cache: speakersCache}).
                success(function (data, status, headers, config) {
                    debugger;

                }).
                error(function (data, status, headers, config) {
                  debugger;
                });
        }

        $scope.checkit = function() {

            var x = speakersCache;
            debugger;

        };




    }]);

答案 2 :(得分:0)

如果我理解你,我做了类似的事情:

我有这段代码:

.factory('myOwnEntity', ['$filter',
        function ($filter) {
            var myOwnList = [];
            return {
                set : function (data) {
                    myOwnList = data;
                },
                get : function () {
                    return myOwnList;
                },
                find : function (id) {
                    return $filter('filter')(myOwnList, { itemId : id }).pop();
                }
            }
        }
    ])

当我向Web服务请愿时,我存储了这样的信息:

$http.get(url, {
    cache : true
})
.success(function (data) {
    myOwnEntity.set(data);
    defer.resolve(data);
});
return defer.promise;

现在,下次我需要一些信息时,我只是使用find方法查询我的实体。希望这是你正在寻找的。