Angularjs - 多个$ http REST调用(第二个调用依赖于第一个输出)

时间:2015-08-21 16:08:30

标签: angularjs http

我是AngularJs世界的新手 - 我正在尝试从两个REST WS调用中获取数据。

第一个返回一组数据(工作正常) - 使用来自第一个数据的数据,我需要进行另一个webservice调用并检索数据并在表格中打印。

以下是我到目前为止所尝试的内容: HTML:

<table ng-table="tableParams" id="request_table" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
    <tr>
        <th>Number</th>
        <th>Price</th>
        <th>Short Description</th>
        <th>Requested for</th>
        <th>State</th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="request in req_list | orderBy:sortType:sortReverse | filter: searchItem">
        <p ng-repeat="item in fetchRequest(request.price)"></p>

        <td>{{request.number }}</td>
        <td>{{request.price}}</td>
        <td>{{request.short_description}}</td>
        <td>{{request.requested_for.display_value}}</td>
        <td>{{request.stage}}</td>
    </tr>

</tbody>

脚本:

            angular.module('sc_request_list')
            .controller('MyRequestItems', [
                '$scope',
                '$http',
                function($scope, $http) {
                    $scope.sortType = 'number' //set the default sort type
                    $scope.sortReverse = false; // set the default sort order
                    $scope.searchItem // set the default search/filter term
                    $scope.itemUrl = '/api/sc_request';
                    $scope.reqUrl = '/api/sc_req_item';
                    $http.defaults.headers.common.Accept = "application/json";
                    $scope.fetchRequestItemList = function() {
                        $http({
                            method: 'GET',
                            url: $scope.itemUrl,
                        }).


                        success(function(data, status) {
                            var result = data;
                            var json = JSON.stringify(result);
                            var data = JSON.parse(json);
                            $scope.req_list = data.result; // response data 

                        }).
                        error(function(data, status) {
                            $scope.req_list = [{
                                "req_list": "Error fetching list"
                            }];
                        });

                    }

                    $scope.fetchRequest = function(request) {
                        console.log("Request Number is: " + request);
                        $http({
                            method: 'GET',
                            url: $scope.reqUrl + "/" + request,
                        }).


                        success(function(data, status) {
                            var result = data;
                            var json = JSON.stringify(result);
                            var data = JSON.parse(json);
                            $scope.req = data.result; // response data 

                        }).
                        error(function(data, status) {
                            $scope.req = [{
                                "req": "Error fetching list"
                            }];
                        });

                    }
                }


            ]);

任何有助于帮助的人。

5 个答案:

答案 0 :(得分:5)

我会这样做,第二次调用成功回复。

function getFirstItem(){           // Here I declare a function that will return a promise.
    return $http({
        method: 'GET',
        url: $scope.itemUrl
    });
}

function getDependantItem(){         // I declare a second function that returns  a promise
    return $http({
        method: 'GET',
        url: $scope.otherUrl
    });
}

$scope.fetchRequest = function(request) {      // Here is a function that can be called by  the view.
    getFirstItem()
        /*
         * I call the first function that returns a promise. 
         * the "then" is just setting a 
         * callback that will be executed when your server will respond.
         * The next thing the code does, after registering the callback,
         * is going to the end of your function,
         * and return nothing.
         */
     .then(function(result1){
        $scope.req = result1.result; // Now that the server has answered, you can assign the value to $scope.req, and then, call the second function.

        getDependantItem().then(function(result2){
            // This is still an async call. The code keeps on running, and
            // you will only have this callback running when your server will have responded

            // Handle your response here and assign your response to a $scope variable.
        }, function(error2){
             // If an error happened during the second call, handle it here.
        });

    }, function(error1){ 
        // If an error happened during first call, handle it here.
    });

    // If you want to return something, you must do it here.
    // Before your promises would ever be resolved
    // That's the reason why you got an undefined
};

关于您的代码,很少有注意事项:

  • 避免.success.error,请使用.then(function(success){}, function(error){});。大多数框架都弃用了这两个第一,并且角度文档根本不再谈论它。
    https://docs.angularjs.org/api/ng/service/ $ Q

  • 避免将所有内容放入$ scope中。只需将需要与视图或其他控制器共享的内容放在一起。

  • 尽快,了解共享功能的服务,并让1层应用程序负责1件事

答案 1 :(得分:3)

使用$ q服务,您可以链接您的承诺对象:

$scope.fn1 = function(){
  var deferred = $q.defer();
  $http.({ method: 'GET', url: 'YOUR_1st_API' }).success(function(data){
    deferred.resolve(data);
  });
  return deferred.promise;
}

$scope.fn2 = function(data){
  var deferred = $q.defer();
  $http.({ method: 'GET', url: 'YOUR_2nd_API' }).success(function(data){
    deferred.resolve(data);
  });
  return deferred.promise;
}

// after $scope.fn1() is done pass data with resolve method to $scope.fn2() , now you can access data from fn1 inside fn2
$scope.fn1().then($scope.fn2);

如果将业务逻辑(例如数据获取)分离到“服务”或“工厂”并将它们注入控制器,那会更好。通过这种方式,您的代码将更易于阅读和维护。

  

More info for $q service

答案 2 :(得分:1)

您的调用是异步调用的,因此在进行调用时,其余代码仍在执行。因此,

<p ng-repeat="item in fetchRequest(request.price)"></p>

request.price被定义之前执行。

您需要做的是将呼叫链接到您的api呼叫:

&#13;
&#13;
$http({
  method: 'GET',
  url: $scope.itemUrl,
}).


success(function(data, status) {
  var result = data;
  var json = JSON.stringify(result);
  var data = JSON.parse(json);
  $scope.req_list = data.result; // response data 
  
  //Loop through requests
  $scope.req_list.foreach(function (elem, index) {
    //chained call is here
    $scope.fetchRequest(elem.price, index);
  });
}).

error(function(data, status) {
  $scope.req_list = [{
    "req_list": "Error fetching list"
  }];
});

$scope.fetchRequest = function(request, index) {
  console.log("Request Number is: " + request);
  $http({
    method: 'GET',
    url: $scope.reqUrl + "/" + request,
  }).

  success(function(data, status) {
    var result = data;
    var json = JSON.stringify(result);
    var data = JSON.parse(json);
    //Attach result of api call to apropriate element of req_list array
    $scope.req_list[index].items = data;

  }).
  error(function(data, status) {
    $scope.req = [{
      "req": "Error fetching list"
    }];
  });

}
}
&#13;
&#13;
&#13;

然后改变:

<p ng-repeat="item in fetchRequest(request.price)"></p>

要:

<p ng-repeat="item in request.items"></p>

答案 3 :(得分:-1)

通常我使用以下模式:

$http({method: 'GET',
       url: '<*whatever url is, no need to put it on $scope, unless you really need it there*>'})
    .success(function(result) { return result.data; })
    .error(function(reason) { <handle your error here> })
    .then(function(data) { <make your second request here with the data you've got from the first> });

答案 4 :(得分:-1)

在第一次成功通话中,您应该拨打第二个:

angular.module('sc_request_list')
    .controller('MyRequestItems', [
        '$scope',
        '$http',

        function($scope, $http) {
            $scope.sortType = 'number' //set the default sort type
            $scope.sortReverse = false; // set the default sort order
            $scope.searchItem // set the default search/filter term
            $scope.itemUrl = '/api/sc_request';
            $scope.reqUrl = '/api/sc_req_item';
            $http.defaults.headers.common.Accept = "application/json";
            $scope.fetchRequestItemList = function() {
                $http({
                    method: 'GET',
                    url: $scope.itemUrl,
                }).
                success(function(data, status) {
                    var result = data;
                    var json = JSON.stringify(result);
                    var data = JSON.parse(json);
                    $scope.req_list = data.result; // response data

                    // Second call
                    $scope.fetchRequest = function(request) {
                        console.log("Request Number is: " + request);
                        $http({
                            method: 'GET',
                            url: $scope.reqUrl + "/" + request,
                        }).
                        success(function(data, status) {
                            var result = data;
                            var json = JSON.stringify(result);
                            var data = JSON.parse(json);
                            $scope.req = data.result; // response data 

                        }).
                        error(function(data, status) {
                            $scope.req = [{
                                "req": "Error fetching list"
                            }];
                        });

                    }

                }).
                error(function(data, status) {
                    $scope.req_list = [{
                        "req_list": "Error fetching list"
                    }];
                });

            }
        }


    ]);
相关问题