在服务中处理 $http 响应
IT技术
javascript
angularjs
angular-http
                    2021-02-04 20:03:08
                
            
        6个回答
            这是一个可以满足您要求的 Plunk:http ://plnkr.co/edit/TTlbSv?p=preview
这个想法是你直接使用 Promise 和它们的“then”函数来操作和访问异步返回的响应。
app.factory('myService', function($http) {
  var myService = {
    async: function() {
      // $http returns a promise, which has a then function, which also returns a promise
      var promise = $http.get('test.json').then(function (response) {
        // The then function here is an opportunity to modify the response
        console.log(response);
        // The return value gets picked up by the then in the controller.
        return response.data;
      });
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
  // Call the async method and then do stuff with what is returned inside our own then function
  myService.async().then(function(d) {
    $scope.data = d;
  });
});
这是一个稍微复杂的版本,它缓存请求,因此您只需第一次创建(http://plnkr.co/edit/2yH1F4IMZlMS8QsV9rHv?p=preview):
app.factory('myService', function($http) {
  var promise;
  var myService = {
    async: function() {
      if ( !promise ) {
        // $http returns a promise, which has a then function, which also returns a promise
        promise = $http.get('test.json').then(function (response) {
          // The then function here is an opportunity to modify the response
          console.log(response);
          // The return value gets picked up by the then in the controller.
          return response.data;
        });
      }
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = {};
  };
  $scope.getData = function() {
    // Call the async method and then do stuff with what is returned inside our own then function
    myService.async().then(function(d) {
      $scope.data = d;
    });
  };
});
让它简单点。就这么简单
promise在您的服务中返回(无需then在服务中使用)then在您的控制器中使用
演示。http://plnkr.co/edit/cbdG5p?p=preview
var app = angular.module('plunker', []);
app.factory('myService', function($http) {
  return {
    async: function() {
      return $http.get('test.json');  //1. this returns promise
    }
  };
});
app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function(d) { //2. so you can use .then()
    $scope.data = d;
  });
});
因为是异步的,所以$scope是在ajax调用完成之前获取数据。
您可以$q在您的服务中使用创建promise并将其返回给控制器,控制器在then()调用中获取结果promise。
在您的服务中,
app.factory('myService', function($http, $q) {
  var deffered = $q.defer();
  var data = [];  
  var myService = {};
  myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
      console.log(d);
      deffered.resolve();
    });
    return deffered.promise;
  };
  myService.data = function() { return data; };
  return myService;
});
然后,在您的控制器中:
app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function() {
    $scope.data = myService.data();
  });
});
tosh shimayama 有一个解决方案,但如果你使用 $http 返回Promise并且Promise可以返回一个值的事实,你可以简化很多:
app.factory('myService', function($http, $q) {
  myService.async = function() {
    return $http.get('test.json')
    .then(function (response) {
      var data = reponse.data;
      console.log(data);
      return data;
    });
  };
  return myService;
});
app.controller('MainCtrl', function( myService,$scope) {
  $scope.asyncData = myService.async();
  $scope.$watch('asyncData', function(asyncData) {
    if(angular.isDefined(asyncData)) {
      // Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
    }
  });
});
在 coffeescript 中的一个小演示:http ://plunker.no.de/edit/ksnErx?live=preview
你的plunker用我的方法更新:http ://plnkr.co/edit/mwSZGK?p=preview
我认为更好的方法是这样的:
服务:
app.service('FruitsManager',function($q){
    function getAllFruits(){
        var deferred = $q.defer();
        ...
        // somewhere here use: deferred.resolve(awesomeFruits);
        ...
        return deferred.promise;
    }
    return{
        getAllFruits:getAllFruits
    }
});
在控制器中,您可以简单地使用:
$scope.fruits = FruitsManager.getAllFruits();
Angular 会自动将解析的awesomeFruits放入$scope.fruits.
其它你可能感兴趣的问题