如何在角度模拟$ http成功?

时间:2016-11-15 19:36:07

标签: javascript angularjs local-storage

我有一个服务,我在我的应用程序中的几个控制器中使用。

该服务包含对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
  });

}]);

我不知道这是否可能,或者我需要改变多少结构以使其成为可能,但如果有人有想法,我会非常感激。

2 个答案:

答案 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模式。