2013-03-08 8 views
98

Ich habe eine einzige Fabrik mit ngResource definiert abzuschließen:AngularJS - warten auf mehrere Ressourcenanfragen

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

ich mehrere Anrufe an die Abfragemethode mache auf dieser Fabrik definiert. Die Anrufe können asynchron geschehen, aber ich muss warten, sowohl vor als abgeschlossen Anrufe weitermachen:

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 
    }; 
}); 

Gibt es eine Möglichkeit, dies mit ngResource, ähnlich wie jQuery $ .when() definiert mit AngularJS Fabriken zu tun, dann.() Funktionalität? Ich würde es vorziehen, jQuery nicht zu meinem aktuellen Projekt hinzuzufügen.

Antwort

188

Sie wollen Versprechungen und $q.all() verwenden.

Im Grunde können Sie es verwenden, um alle Ihre $ Ressourcen oder $ http Anrufe zu wickeln, weil sie Versprechungen zurückgeben.

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

Ressourcen geben keine Versprechen ab, sie geben Objekte zurück, die in Zukunft gefüllt werden. In der Version * unstable * 1.1.3 haben Ressourcen jedoch auch die Eigenschaft '$ then ', stellen jedoch kein Versprechensobjekt zur Verfügung. Exposed '$ Versprechen' vollständig wäre in 1.1.4 –

+0

@ UmurKontacı Dies ist leider * nicht * in eckigen 1.1.4! – nh2

+0

Details zu den * Ressourcen sind kein Versprechen Problem * kann in [this thread] (https://groups.google.com/forum/#!msg/angular/N5yBJvl7Pbg/C48oelQu6DgJ) und in [dieser Pull-Anfrage] (https://github.com/angular/angular.js/pull/2060#issuecomment-17026079). – nh2

16

Ich denke, eine bessere Lösung ist:

$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

Für mich am Ende ohne $ Versprechen gearbeitet ... Genau wie: Account.query ({type: 'billing'}), Account.query ({type: 'shipping'}) – georgeos

10

Die Lösung von Ben Lesh das Beste ist, aber es ist nicht vollständig. Wenn Sie Fehlerbedingungen behandeln müssen - und, ja, Sie tun - dann müssen Sie die catch Methode auf das Versprechen API wie folgt verwenden:

$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... 

}); 

Wenn Sie nicht catch und alle Ihre Versprechen definieren scheitern, dann wird die then Methode nie ausgeführt und wird daher wahrscheinlich Ihre Schnittstelle in einem schlechten Zustand verlassen.

Verwandte Themen