Einer meiner AngularJS-Controller enthält diese Zeile:
api.tickets.query()
das api
-Modul enthält Folgendes:
angular.module('myapp.api', [
'ngResource'
])
.factory('api', function($resource, applicationsService) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: $resource('tickets', {
applicationId: fetchAppId
}),
...
}
applicationsService.getCurrentApp () führt selbst einen $ http-Aufruf aus. So können Sie das Problem vielleicht sehen - dieser Aufruf wurde möglicherweise nicht gelöst, wenn fetchAppId () zurückkehrt.
Wie kann ich das umgehen?
Nehmen wir an, Daten, die auf asynchrone Weise von applicationsService
zurückgegeben werden, lauten wie folgt:
var data = [
{
"PreAlertInventory": "5.000000",
"SharesInInventory": "3.000000",
"TotalSharesSold": "2.000000"
}
und applicationsService
factory geben Versprechen zurück:
.factory('applicationsService', ['$resource','$q', function($resource, $q) {
var data = [
{
"PreAlertInventory": "5.000000",
"SharesInInventory": "3.000000",
"TotalSharesSold": "2.000000"
}
];
var factory = {
getCurrentApp: function () {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Ich würde einfach api.tickets()
anrufen
$scope.data = api.tickets();
aber unser api
service sieht so aus:
.factory('api', function($resource, applicationsService,$q, $timeout) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: function() {
var deferred=$q.defer();
fetchAppId().then(function(data) { // promise callback
$timeout(function(){ // added dummy timeout to simulate delay
deferred.resolve(data);
}, 3000);
});
return deferred.promise;
}
}
});
Demo Fiddle
Sie müssen ein Versprechen für sich selbst erstellen.
.factory('api', function($resource, applicationsService,$q) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: function() {
var defer=$q.defer();
fetchAppId().then(function(data) {
var appId=data;
$resource('tickets', {applicationId: appId})
.then(function(data) {
defer.resolve(data);
})
}
return defer.promise;
}
}
Wenn Sie warten möchten, dass eine Winkelressource ($resource
) aufgelöst wird, bevor Sie die Route ändern, müssen Sie den $promise
zurückgeben.
$routeProvider.when('/tickets', {
resolve: {
'tickets': function ('Ticket') {
// do this to resolve the async call prior to controller load
return Ticket.query().$promise;
// this will resolve 'tickets' during/after controller load
return Ticket.query();
}
},
controller: ...
});