将 $http 调用抽象为服务 [英] Abstracting $http calls into service

查看:21
本文介绍了将 $http 调用抽象为服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm wondering what the best way to abstract $http calls into an angularjs service is. I've done a bit of research and this seems to be the most common way:

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 做任何事情.

But the problem with this approach is I can't figure out how to do anything on .error.

我更喜欢在我的控制器中包含我的 .success 和 .error 回调.

I'd prefer to have my .success and .error callbacks inside my controller.

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

Is there a way to abstract the http call inside the service whilst maintaining .error and .success callbacks inside the controller?

谢谢.

推荐答案

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

You can still use the on success/error calls.

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

The method you've highlighted returns a "Promise" object. A good thing about promises is that they are chainable.

假设您希望响应控制器中的 $http 请求错误:

So say you wish to respond to a $http request error in your controller:

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
  });
}

注意:接下来的部分不再适用.当承诺解析时,模板中使用的承诺不再自动解析为其值.

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

You should also understand why assigning $scope.foo works in your templates. AngularJS has a bit of magic that will resolve any promises to the object you need in a template. So while your template might reference foo.bar and the output will be correct, whats actually happening in the background is that the template is waiting for the promise to be fulfilled before rendering that part of the template.

另外,另一个问题是,如果您正在处理链中某处的错误,请记住返回一个被拒绝的承诺.

Also, another gotcha is to remember to return an rejected promise if you're handling the error somewhere up in the chain.

例如:

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
  });
}

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

If we didn't return a rejected promise in the service, the controller's 'success' code path will be run instead of the reject path.

这篇关于将 $http 调用抽象为服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆