2015-10-15 259 views
1

我使用angularjs的$ http方法獲取多個「父」元素。在這個Ajax調用.success方法中,我必須迭代父元素,並對每個父元素使用另一個Ajax調用來獲取其各自的子元素。我最終想要的是一個包含所有子元素對象的數組,因此我可以使用ng-repeat來顯示它們。這就是爲什麼我要首先收集數組中的所有子元素,並將該數組寫入到我用來顯示的範圍數組中,所以角度只會在收集所有子元素時更新。我並不擅長使用承諾,但我認爲這應該可以通過使用它們。結構基本上是:在另一個Ajax請求中處理多個Ajax請求

.success(function(parentElements){ 
        var tempChildElements = []; 
        $.each(parentElements, function(i, parentElement){ 
         getChildElements(parentElement) 
          .success(function(childElements){ 
           tempChildElements.concat(childElements); 
          }) 
         }) 
        }); 
    $scope.childElements = tempChildElements; 
}); 

基本上,我需要知道什麼時候jQuery.each中的所有請求都完成了。

編輯:

於是,我改變了我的代碼,以將您的答案,我想我接近,但它仍然沒有工作。我得到的是:

$scope.loadChildren = function(){ 
      var tempchildren = []; 
      var promises = []; 
      restApi.getOwnparents() //Returns $http.get promise 
       .then(function(parents){ 

        parents.data.forEach(function(parent, i, parents){ 
         promises.push(restApi.getOwnchildren(parent) //Returns $http.get promise 
          .then(function(children){ 

           tempchildren = tempchildren.concat(children.data); 
          },function(msg){ 
           console.log(msg); 
          })); 

        }); 
       }, function(msg){ 
        console.log(msg); 
       }); 
      $q.all(promises).then(function(data){ 
       //Never gets called 
       $scope.currentElements = tempchildren; 
       console.log(tempchildren); 
      }); 
     }; 

編輯2: 我得到了它使用從你們的建議的工作,下面是我的代碼。隨意分享改進。

$scope.loadparents = function(){ 
var tempchildren = []; 
var promises = []; 
restApi.getOwnparents() 
    .then(function(parents){ 
     parent.data.forEach(function(parent, i, parents){ 
      promises.push(restApi.getOwnchildren(parent));    
     }); 
     $q.all(promises).then(function(data){ 
      console.log(data); 
      data.forEach(function(children){ 
       tempchildren = tempchildren.concat(children.data); 
      }); 
      $scope.currentElements = tempchildren; 
     }); 
    }); 

};

+0

首先擺脫'$,each'如果'parentelements'是一個數組,你可以使用本地'forEach',否則使用'angular.forEach'。看看'$ q.all'它會在所有解決方案調用它的'then'後運行一系列promise – ste2425

回答

1

像這樣的東西可能是可能的。通過您的parentElements環通該元素調用getChildElements。但是,如果您返回$http調用,將其推入陣列並將該陣列傳遞到$q.all,則getChildElements的響應將成爲承諾。當你所有的阿賈克斯電話解決如此將$q.all

var parentElements = [10, 20, 30, 40], 
     promises = []; 

    parentElements.forEach(function(i){ 
     //Each method is actually called here 
     promises.push(getChildElements(i)); 
    }); 

    //$q.all will resolve once all of your promises have been resolved. 
    $q.all(promises) 
     .then(function (data){ 
      //handle success 
      console.log('All Good', data); 
      //Modify your response into what ever structure you need, map may be helpfull 
      $scope.childElements = data.map(); 
     }); 

最有可能你的Ajax調用不會由數組傳遞給$q.all時間分辨但是關於承諾的另一個好處是,即使他們都解決$q.all將解決馬上來代替。

看到它的行動。 http://jsfiddle.net/ht9wphg8/

1

每個請求本身都會返回一個承諾,然後可以放入一個數組並將該數組傳遞給$q.all()

success()回調已被棄用,並且由於您需要返回承諾,因此無論如何您需要在原始請求回調中使用then()

這裏有一個樣本工廠,這將使所有的請求,並做一次,你將有第一個請求的父數據返回到控制器:

app.factory('DataService', function($http, $q) { 
    return { 
    getData: function() { 
     // return initial promise 
     return $http.get('parent.json').then(function(resp) { 
     var parentArr = resp.data; 
     // create array of promises for child data 
     var promises = parentArr.map(function(parentItem, i) { 
      // return each child request promise to the array 
      return $http.get('child.json').then(function(resp) { 
      console.log('Child request #' + (i + 1) + ' completed'); 
      // update parent item 
      parentItem.child = resp.data 
      }); 
     }); 
     // return the promise wrapping array of child promises 
     return $q.all(promises).then(function() { 
      console.log('All requests completed'); 
      // when all done we want the parent array returned 
      return parentArr; 
     }); 
     }); 
    } 
    }; 
}); 

app.controller('MainCtrl', function($scope, DataService) { 
    DataService.getData().then(function(parentArr) { 
    console.log('Add data to scope') 
    $scope.parentArr = parentArr; 
    }); 

}); 

DEMO