4

我想知道将 $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 回调?

谢谢你。

4

1 回答 1

4

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

您突出显示的方法返回一个“Promise”对象。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
  });
}

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

于 2013-07-28T23:35:22.780 回答