AngularJS $http returns 未定义?

AngualrJS $http returns undefined?

根据 AngularJS,我的 $http 通过我的控制器的服务调用是 return 未定义?

这似乎是什么问题?我正在尝试 return 调用的数据,但是一旦传递给控制器​​,数据就变得未定义了?

JavaScript

var myStore = angular.module('myStore', [])

    .controller('StoreController', ['$scope', 'dataService', function ($scope,  dataService) {
      $scope.products = dataService.getData();
    }])

    .service('dataService', ['$http', function($http) {
      this.getData = function() {
        $http.get('assets/scripts/data/products.json')
              .then(function(data) {
                return data;
              });
      };
    }]);

HTML

<div class="content">
  <ul>
    <li ng-repeat="product in products.products">{{product.productName}}</li>
  </ul>
</div>

我明白 $http$q$resource 都是 return 承诺,但我想我已经用 .then.

涵盖了它

问题可能是您没有在 dataService.getData 函数中 returning 由 $http.get 创建的承诺。换句话说,你可以通过改变你所拥有的来解决你的undefined问题:

.service('dataService', ['$http', function($http) {
    this.getData = function() { 
        return $http.get...
    };
}

如果您在 dataService.getData 内多次调用 $http.get,请按以下方式处理它们。

.service('dataService', ['$http', function($http) {
    this.getData = function() {
        var combinedData, promise;
        combinedData = {};
        promise = $http.get(<resource1>);
        promise.then(function (data1) {
            combinedData['resource1Response'] = data1;
            return $http.get(<resource2>);
        });
        return promise.then(function (data2) {
            combinedData['resource2Response'] = data2;
            return combinedData;
        });
    };
}]);

然而,更简洁的方法是使用 $q.all

.service('dataService', ['$http', '$q', function($http, $q) {
    this.getData = function() {
        var combinedData, promises;
        combinedData = {};
        promises = $q.all([
            $http.get(<resource1>),
            $http.get(<resource2>)
        ]);
        return promises.then(function (allData) {
            console.log('resource1 response', allData[0]);
            console.log('resource2 response', allData[1]);
            return allData;
        });
    };
}]);

您的问题确实在于您没有 return 承诺,但正如您在@maxenglander 的 post 中所述,您可能涉及多个 http 调用,这意味着您应该开始使用 $q 创建和解决您自己的承诺:

.service('dataService', ['$http', '$q', function($http, $q) {
      return $http.get('assets/scripts/data/products.json')
          .then(function(data) {
            //possibly do work on data
             return <<mutated data>>;
            });
}];

或者如果您有多个 http 调用并且需要做一些组合工作,您可以做一些事情 $q.all:

.service('dataService', ['$http', '$q', function($http, $q) {
      var p1 = $http.get('assets/scripts/data/products.json');
      var p2 = $http.get('assets/scripts/data/products2.json');
      return $q.all([p1, p2]).then(function(result){
         //do some logic with p1 and p2's result
         return <<p1&p2s result>>;
       });
}];

然后在你的控制器中你需要做:

.controller('StoreController', ['$scope', 'dataService', function ($scope,  dataService) {
     dataService.getData().then(function(result){
         $scope.products = result;
     });
}]);

这在您的服务中允许的是,您现在可以进行复杂的调用,比如在内部调用两个 Web 服务并等待它们都完成,然后再解决承诺。 我在这里想表达的是,您不需要 return $http.get 函数提供的承诺,但是由于您正在执行异步操作,因此您 DO 需要 return 一些稍后会兑现并付诸行动的承诺。