0

我有一个使用缓存库(ngStorage)实现的 $resource 工厂。我将资源缓存添加到 localstorage 并进行检查以确保缓存是最新且有效的。

然而,我遇到了几个我正在努力纠正的问题。第一个是每次我加载缓存的数据时,缓存都会检查服务器以查看是否有新数据要检索和缓存。在它收集这些数据之后,我希望将最后一个数据点对象存储在缓存中,这样我就知道缓存中的最后一个时间点是什么。

第二个问题是我希望我的视图在路由更改完成之前等待创建缓存。我在我的控制器视图上设置了一个解析属性,但是我不确定在哪里实现 $q 承诺以能够解决承诺并确保数据存在。

我的代码如下:

$资源:

angular.module('resources.readings', ['ngResource', 'ngStorage']).
    factory('Reading', function($resource, $localStorage, $sessionStorage) {
        var resource = $resource('api/index.php/readings/:id', {}, {
            'update': {method: 'PUT'}
        });

        var readingsCache = $localStorage.$default({
            readings: [],
            lastReading: null,
            lastUpdate: null,
            newestReading: null,
            firstReading: null
        });

        var pageLimit = 1000;
function subtractDays(date, days) {
            var result = new Date(date);
            result.setDate(date.getDate() - days);
            return result;
        }

        var refreshCache = function(loadDefault) {
            var endDate = new Date(readingsCache.newestReading._time);
            if (loadDefault) {
                var startDate = subtractDays(endDate, 1).toISOString();
            } else {
                var startDate = new Date(readingsCache.lastReading._time).toISOString();
            }
            endDate = endDate.toISOString();
            resource.get({q: 'getCount', startDate: startDate, endDate: endDate}, function(response) {
                var numPages = Math.ceil(response.totalCount / pageLimit);
                for (var i = 0; i < numPages; i++) {
                    resource.query({startDate: startDate, endDate: endDate, limit: pageLimit, page: i}, function(response) {
                        response.forEach(function(val, index, theArray) {
                            readingsCache.readings.push(val);
                        });
                    }, function(data) {
                        //a single reading call has failed
                    });
                }
            }, function(data) {
                //failure of getting count
            });
        }

        resource.getLastUpdate = function() {
            resource.get({q: 'getLastUpdate'}, function(response) {
                //assume cache is empty and needs to be filled
                var loadDefault = true;
                //if we have cached data, and theres new data to get, don't load the default value of a day
                if (readingsCache.newestReading && readingsCache.newestReading._ID !== response._ID) {
                    readingsCache.lastReading = readingsCache.newestReading;
                    readingsCache.newestReading = response;
                    loadDefault = false;
                    refreshCache(loadDefault);
                } else if (!readingsCache.lastUpdate) {
                    readingsCache.newestReading = response;
                    refreshCache(loadDefault);
                }
                readingsCache.lastUpdate = new Date();
                //                readingsCache.firstReading = readingsCache.readings[readingsCache.readings.length - 1];
            }, function(data) {
                //timeout and try again
            });
            return readingsCache;
        }
return resource;
    });

还有我的路线和控制器:

angular.module('temperature.readings', ['resources.readings', 'highcharts-ng'])
    .config(['$routeProvider', function($routeProvider) {
            var deferredReadingCache = ['Reading', '$q', function(Reading, $q) {
                    return Reading.getLastUpdate();
             }];
$routeProvider
                    .when('/readings', {
                        templateUrl: 'js/app/readings/reading-list.tpl.html',
                        controller: 'ReadingsListCtrl',
                        resolve: {
                            readingCache: deferredReadingCache
                        }
                    })
}])
    .controller('ReadingsListCtrl', ['$scope', '$location', '$route', 'Reading',     function($scope, $location, $route, Reading) {
            $scope.order = '_ID';
            $scope.reverse = false;
            $scope.readingCache = $route.current.locals.readingCache;
4

1 回答 1

0

我最终需要做的是为整个代码块返回创建一个承诺,而且当资源查询服务器并循环它以填充缓存时,我还需要在那里添加一个解析以确保循环已完成填充允许在页面上呈现之前的缓存。这是我的“最终”代码:

var deferred = $q.defer();
            //assume cache is empty and needs to be filled
            var loadDefault = true;
            var cached = false;
            resource.get({q: 'getLastUpdate'}).$promise.then(function(response) {
                //if we have cached data, and theres new data to get, don't load the default value of an hour
                if (readingsCache.newestReading && readingsCache.newestReading._ID === response._ID) {
                    cached = true;
                    deferred.resolve(readingsCache);
                } else if (readingsCache.newestReading && readingsCache.newestReading._ID < response._ID) {
                    readingsCache.lastReading = readingsCache.newestReading;
                    readingsCache.newestReading = response;
                    loadDefault = false;
                } else if (!readingsCache.lastUpdate) {
                    readingsCache.newestReading = response;
                }

                readingsCache.lastUpdate = new Date();

                endDate = new Date(readingsCache.newestReading._time);
                if (loadDefault) {
                    startDate = subtractMinutes(endDate, 60).toISOString();
                } else {
                    startDate = new Date(readingsCache.lastReading._time).toISOString();
                }
                endDate = endDate.toISOString();
                if (cached) {
                    deferred.resolve(readingsCache);
                } else {
                    var totalCount = null;
                    resource.get({q: 'getCount', startDate: startDate, endDate: endDate}).$promise.then(function(response) {
                        var numPages = Math.ceil(response.totalCount / pageLimit);
                        totalCount = response.totalCount;
                        for (var i = 0; i < numPages; i++) {
                            resource.query({startDate: startDate, endDate: endDate, limit: pageLimit, page: i}).$promise.then(
                                    function(response) {
                                        response.forEach(function(val, index, theArray) {
                                            readingsCache.readings.push(val);
                                            if (readingsCache.readings.length >= totalCount) {
                                                if (loadDefault) {
                                                    readingsCache.firstReading = readingsCache.readings[0];
                                                }
                                                deferred.resolve(readingsCache);
                                            }
                                        });
                                    });
                        }
                    });
                }
            });
            return deferred.promise;
        }
于 2013-11-15T12:26:38.403 回答