2013-03-08 14 views
98

mam jedną fabrykę zdefiniowany z ngResource:angularjs - czekać na wielu zapytań zasobów do ukończenia

App.factory('Account', function($resource) { 
    return $resource('url', {}, { 
     query: { method: 'GET' } 
    }); 
}); 

ja Wykonywanie wielu połączeń do określonej metody zapytań w tej fabryce. Połączenia mogą zdarzyć asynchronicznie, ale muszę czekać na zarówno wzywa do zakończenia przed kontynuowaniem:

App.controller('AccountsCtrl', function ($scope, Account) { 
    $scope.loadAccounts = function() { 
     var billingAccounts = Account.query({ type: 'billing' }); 
     var shippingAccounts = Account.query({ type: 'shipping' }); 

     // wait for both calls to complete before returning 
    }; 
}); 

Czy istnieje sposób to zrobić z angularjs fabryk określonych z ngResource, podobnie jak jQuery .Przy $() wtedy.() funkcjonalność? Wolałbym nie dodawać jQuery do mojego bieżącego projektu.

Odpowiedz

188

Będziesz chciał użyć obietnic i $q.all().

Zasadniczo można go użyć do zawinięcia wszystkich wywołań $ resource lub $ http, ponieważ zwracają obietnice.

function doQuery(type) { 
    var d = $q.defer(); 
    var result = Account.query({ type: type }, function() { 
     d.resolve(result); 
    }); 
    return d.promise; 
} 

$q.all([ 
    doQuery('billing'), 
    doQuery('shipping') 
]).then(function(data) { 
    var billingAccounts = data[0]; 
    var shippingAccounts = data[1]; 

    //TODO: something... 
}); 
+16

Zasoby nie zwracają obietnic, zwracają obiekty do wypełnienia w przyszłości. Jednak w wersji * unstable * 1.1.3 zasoby mają również właściwość '$ then', ale nie ujawniają żadnego obiektu obietnicy. Wystawianie "$ promise" całkowicie byłoby w 1.1.4 –

+0

@ UmurKontacı To jest niestety * nie * w kątowym 1.1.4! – nh2

+0

Szczegóły na temat * zasobów nie stanowią obietnicy problemu * można znaleźć w [tym wątku] (https://groups.google.com/forum/#!msg/angular/N5yBJvl7Pbg/C48oelQu6DgJ) oraz w [tym żądaniu pobierania] (https://github.com/angular/angular.js/pull/2060#issuecomment-17026079). – nh2

16

Myślę, że lepszym rozwiązaniem jest:

$q.all([ 
    Account.query({ type: 'billing' }).$promise, 
    Account.query({ type: 'shipping' }).$promise 
]).then(function(data) { 
    var billingAccounts = data[0]; 
    var shippingAccounts = data[1]; 

    //TODO: something... 
}); 
+1

Dla mnie pracował bez obietnicy $ na koniec ... Tak jak: Account.query ({type: 'billing'}), Account.query ({type: 'shipping'}) – georgeos

10

Rozwiązanie z Ben Lesh jest najlepszy, ale to nie jest kompletna. Jeśli trzeba obsłużyć warunków błędów - i tak, to zrobić - wtedy trzeba zastosować metodę catch na API jak ta obietnica:

$q.all([ 
    doQuery('billing'), 
    doQuery('shipping') 
]).then(function(data) { 
    var billingAccounts = data[0]; 
    var shippingAccounts = data[1]; 

    //TODO: something... 

}).catch(function(data) { 

    //TODO: handle the error conditions... 

}).finally(function() { 

    //TODO: do final clean up work, etc... 

}); 

Jeśli nie definiują catch i wszystkich obietnic niepowodzenie, a następnie metoda then nigdy nie zostanie wykonana i prawdopodobnie pozostawi interfejs w złym stanie.

Powiązane problemy