webentwicklung-frage-antwort-db.com.de

Warten auf Versprechen, bevor das Laden der Ressource ausgeführt wird

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?

7
Bilal and Olga

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

7
Maxim Shoustin

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;
     }
   }
4
Chandermani

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: ...
});
1
Aleck Landgraf