将$ http调用抽象为服务

时间:2013-07-28 23:16:43

标签: angularjs angularjs-service

我想知道将$ http调用抽象为angularjs服务的最佳方法是什么。我做了一些研究,这似乎是最常见的方式:

app.factory('myService', function($http) {
 return {
   getFoo: function() {
     return $http.get('foo.json').then(function(result) {
       return result.data;
     });
   }
 }
});

app.controller('MainCtrl', function($scope, myService) {
  //the clean and simple way
  $scope.foo = myService.getFoo();
}

但这种方法的问题是我无法弄清楚如何对.error做任何事情。

我更喜欢在我的控制器中使用.success和.error回调。

有没有办法在服务中抽象http调用,同时在控制器内维护.error和.success回调?

谢谢。

1 个答案:

答案 0 :(得分:4)

您仍然可以使用on success / error calls。

您突出显示的方法会返回"Promise"个对象。承诺的一个好处是它们是可链接的。

所以说你想回应控制器中的$ http请求错误:

app.factory('myService', function($http) {
 return {
   getFoo: function() {
     return $http.get('foo.json').then(function(result) {
       return result.data;
     });
   }
 }
});

app.controller('MainCtrl', function($scope, myService) {
  //the clean and simple way
  $scope.foo = myService.getFoo().then(function(){
    //Do something with successful response
  }, function(){
    //Do something with unsuccessful response
  });
}

注意:下一节不再适用。当promise解析时,模板中使用的Promise不再自动解析为其值。

您还应该了解为什么在模板中分配$scope.foo。 AngularJS有一些魔力可以解决模板中所需对象的任何承诺。因此,虽然您的模板可能引用foo.bar并且输出将是正确的,但实际上在后台发生的是模板在渲染模板的这一部分之前等待履行的承诺。

另外,另一个问题是如果你在链中的某个地方处理错误,则要记住返回被拒绝的承诺。

例如:

app.factory('myService', function($http, $q) {
 return {
   getFoo: function() {
     return $http.get('foo.json').then(function(result) {
       return result.data;
     }, function(result){
      //I'm doing something here to handle the error
      return $q.reject(result);
     });
   }
 }
});

app.controller('MainCtrl', function($scope, myService) {
  //the clean and simple way
  $scope.foo = myService.getFoo().then(function(){
    //Do something with successful response
  }, function(){
    //Do something with unsuccessful response
  });
}

如果我们未在服务中返回被拒绝的承诺,则将运行控制器的“成功”代码路径,而不是拒绝路径。