我有一个服务,我在我的应用程序中的几个控制器中使用。
该服务包含对php脚本的$ http调用,该脚本返回一些重要数据。
我想要做的是在请求失败时从用户localstorage
获取数据,然后在所有控制器中调用绑定到$ http成功的所有函数。
这是我服务的一部分:
app.service('initialJSON', ['$http', function ($http) {
var vm = this;
vm.json = $http.get(url);
vm.json.success(function (data) {
if (typeof Storage !== "undefined") {
localStorage.initialJSON = data;
}
})
vm.json.error(function (data, status) {
if (typeof Storage !== "undefined" && "initialJSON" in localStorage) {
// call all success functions in all controllers with the locally saved data
}
});
}]);
作为示例,应该调用此控制器中的函数:
app.controller('someCtrl', ['initialJSON', function(initialJSON) {
var vm = this;
initialJSON.json.success(function (data) {
// This function should be called and do some things with the data
});
}]);
我不知道这是否可能,或者我需要改变多少结构以使其成为可能,但如果有人有想法,我会非常感激。
答案 0 :(得分:2)
不要让您的控制器重复使用相同的$ http承诺,而是创建自己的,您将在获得结果后通过结果解析。
app.service('initialJSON', ['$http', '$q', function ($http, $q) {
var vm = this;
var deferred = $q.defer();
vm.json = deferred.promise;
var request = $http.get(url);
request.then(function (response) {
if (typeof Storage !== "undefined") {
localStorage.initialJSON = response.data;
deferred.resolve(response.data);
}
})
request.catch(function () {
if (typeof Storage !== "undefined" && "initialJSON" in localStorage) {
deferred.resolve(localStorage.initialJSON);
}
});
}]);
如果你的控制器只关心成功,那么上面应该有效。如果您需要它们以便能够处理错误,那么在尝试获取数据之后,您需要以某种方式扩展它以调用deferred.reject()
。
答案 1 :(得分:-1)
您可以使用本地存储和Cookie:https://github.com/grevory/angular-local-storage
或者,如果你正在寻找一些更具架构的东西:https://github.com/angular-pouchdb/angular-pouchdb
当你说“调用所有成功函数”时,你应该将这些调用包装在一个承诺中。所以服务可能看起来像:
service('myService', ['$q',function($q){
var _privateServiceCall = function(){
return myPromiseBasedCall().then(
function(response){return response;}
).catch(function(err){
throw(err);
});
};
return {
publicServiceCall = function(){
var defer = $q.defer();
_privateServiceCall().then(function(response){
defer.resolve(response);
}).catch(function(err){
throw err;
})
return defer.promise;
}
}
}]);
当控制器需要来自服务的数据时,它将请求该数据,并且当它准备就绪时,将解决这些承诺。
.controller('myController', ['$scope', 'myService', function($scope, myService){
myService.publicServiceCall().then(function(response){
console.log(response);
});
}
}]);
如果您想在某些设置的时间表等上更新数据时设置广播,您可以在服务中使用rootscope广播,并在控制器中使用范围侦听器(范围继承rootscope,但不会导致内核泄漏,如rootscope听众呢)。但是,您应该尽可能使用promises模式。