抽象$ HTTP调用到服务抽象、HTTP

2023-09-13 04:52:48 作者:我爱的少年他如歌—EXO

我不知道抽象$ 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.

我倒是preFER有我的控制器内我.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?

感谢您。

推荐答案

您仍然可以使用成功/错误的电话。

You can still use the on success/error calls.

您已经强调回报无极对象的方法。有关承诺一个好处是,它们是可链接。

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

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

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.