我是AngularJS的新手,我仍然试图利用服务将数据提取到我的应用程序中。
我正在寻找一种方法来缓存$http.get()
的结果,这将是一个JSON数组。在这种情况下,它是一个静态的事件列表:
[{ id: 1, name: "First Event"}, { id: 2, name: "Second Event"},...]
我正在使用一项服务来缓存这些结果:
appServices.service("eventListService", function($http) {
var eventListCache;
this.get = function (ignoreCache) {
if (ignoreCache || !eventListCache) {
eventListCache = $http.get("/events.json", {cache: true});
}
return eventListCache;
}
});
现在从我能理解的情况来看,我正在回复一个"承诺"来自$http.get
函数,我在控制器中添加了一个成功的回调函数:
appControllers.controller("EventListCtrl", ["$scope", "eventListService",
function ($scope, eventListService) {
eventListService.get().success(function (data) { $scope.events = data; });
}
]);
这对我来说很好。我要做的是向eventListService
添加一个事件,以从eventListCache
中提取特定事件对象。
appServices.service("eventListService", function($http) {
var eventListCache;
this.get = function (ignoreCache) { ... }
//added
this.getEvent = function (id) {
//TODO: add some sort of call to this.get() in order to make sure the
//eventListCache is there... stumped
}
});
我不知道这是否是接近缓存的最佳方式,或者这是一件愚蠢的事情,但我试图从一个可能缓存或不缓存的数组中获取单个对象。或者我可能应该调用原始事件并将对象拉出控制器中的结果数组。
答案 0 :(得分:3)
你走在正确的轨道上。 Angularjs中的服务是singeltons,因此使用它来缓存你的$ http请求很好。如果你想在你的服务中公开几个函数,我会做这样的事情。我使用Angularjs中的$ q promise / deferred服务实现来处理asynchronus http请求。
appServices.service("eventListService", function($http, $q) {
var eventListCache;
var get = function (callback) {
$http({method: "GET", url: "/events.json"}).
success(function(data, status) {
eventListCache = data;
return callback(eventListCache);
}).
}
}
return {
getEventList : function(callback) {
if(eventListCache.length > 0) {
return callback(eventListCache);
} else {
var deferred = $q.defer();
get(function(data) {
deferred.resolve(data);
}
deferred.promise.then(function(res) {
return callback(res);
});
}
},
getSpecificEvent: function(id, callback) {
// Same as in getEventList(), but with a filter or sorting of the array
// ...
// return callback(....);
}
}
});
现在,在您的控制器中,您所要做的就是这个;
appControllers.controller("EventListCtrl", ["$scope", "eventListService",
function ($scope, eventListService) {
// First time your controller runs, it will send http-request, second time it
// will use the cached variable
eventListService.getEventList(function(eventlist) {
$scope.myEventList = eventlist;
});
eventListService.getSpecificEvent($scope.someEventID, function(event) {
// This one is cached, and fetched from local variable in service
$scope.mySpecificEvent = event;
});
}
]);
答案 1 :(得分:1)
你走在正确的轨道上。这里有一点帮助:
appServices.service("eventListService", function($http, $q) {
var eventListCache = [];
function getList(forceReload) {
var defObj = $q.defer(), listHolder;
if (eventListCache.length || forceReload) {
listHolder= $http.get("/events.json", {cache: true});
listHolder.then(function(data){
eventListCache = data;
defObj.resolve(eventListCache);
});
} else {
defObj.resolve(eventListCache);
}
return defObj.promise;
}
function getDetails(eventId){
var defObj = $q.defer();
if(eventId === undefined){
throw new Error('Event Id is Required.');
}
if(eventListCache.length === 0){
defObj.reject('No Events Loaded.');
} else {
defObj.resolve(eventListCache[eventId]);
}
return defObj.promise;
}
return {
eventList:getList,
eventDetails:getDetails
};
});
然后,在您的控制器中,您可以像这样处理它:
appControllers.controller(“EventListCtrl”,[“$ scope”,“eventListService”, function($ scope,eventListService){ var eventList = eventListService.getList(); eventList.then(功能(数据){ $ scope.events = data; });
$scope.getEventsList = function(reloadList){
eventList = eventListService.getList(reloadList);
eventList.then(function(data){
$scope.events = data;
});
};
$scope.getEventDetails = function(eventID){
var detailsPromise = eventListService.getDetails(eventID);
detailsPromise.then(function(data){
$scope.eventDetails = data;
}, function(reason){
window.alert(reason);
});
}
}
]);
这样,您的事件在控制器首次加载时加载,然后您可以选择通过传入布尔值来请求新列表。获取事件详细信息也由内部承诺处理,以便在不产生破坏性错误的情况下为您提供一些错误处理。