2013-08-02 8 views
12

Potrzebuję uzyskać pewne informacje (schemat) z serwera, zanim skonfiguruję pakiet usług zależnych od tych informacji.Wstrzykiwanie rozwiązanej obietnicy do usługi

Mój serwer udostępnia schemat definiujący różne właściwości modelu. W moim kątowej kodu, mam usługę, która dostaje ten schemat:

services.factory('schema', function($q, $http) { 
    var deferred = $q.defer(); 
     $http.get('schema/').then(function(response) { 
     schema = // some function of response.data 
     deferred.resolve(schema); 
    }, function() { 
     deferred.reject('There was a problem fetching the schema'); 
    }); 
     return deferred.promise; 
}); 

chciałbym wstrzyknąć obiektu schematu, a nie obietnicy, z innymi usługami, które zależą od schematu. $ RouteProvider pozwala nam robić to dla kontrolerów:

app.config(function($routeProvider) { 
    $routeProvider. 
     when('/', { 
      controller: 'SomeCtrl', 
      resolve: { 
       schema: 'schema' 
      }, 
      ... 
     }); 
}); 

a to pozwala mi określić SomeCtrl tak:

controllers.controller('SomeCtrl', function($scope, schema) { 
    // schema is an object 
    ... 
}); 

Ale za usługi, mam do zrobienia:

services.factory('SomeService', function(schema) { 
    // schema is a promise 
    schema.then(function(schema) { 
     ... 
    }); 
}); 

Czy w jaki sposób mogę to zrobić?

+0

Nie, to po prostu, jak to działa, przynajmniej na razie. – aet

+0

Kątowy router czeka na wartości w ciągu 'resolve', aby rozwiązać/odrzucić przed utworzeniem kontrolera. Następnie wykorzystuje lokalne wartości do wstrzyknięcia do kontrolera (kątowy wtryskiwacz preferuje locals). TL; DR: pracujesz z dwoma różnymi "schematami". –

Odpowiedz

-1

Dostajesz obietnicę, ponieważ twoja funkcja usługowa natychmiast ocenia jej ciało, gdy ją wywołujesz (w zależności od funkcji). Zwykle usługa powinna zwracać obiekt, aby konsument (inna usługa, kontroler, cokolwiek) mógł następnie wywoływać funkcje tego obiektu, gdy zajdzie taka potrzeba.

services.factory('schema', function($q, $http) { 
return { 
    get: function() { 
    var deferred = $q.defer(); 
    $http.get('schema/').then(function(response) { 
     schema = // some function of response.data 
     deferred.resolve(schema); 
    }, function() { 
     deferred.reject('There was a problem fetching the schema'); 
    }); 
    return deferred.promise; 
    } 
} 

});

+0

W twoim przykładzie metoda 'get' nadal zwraca obietnicę, a nie rezolucję obietnicy, o co pyta. –

5

Co chcesz, to odroczony bootstrap. Istnieje już wtyczka do tego napisana - https://github.com/philippd/angular-deferred-bootstrap.

tworzę przykład w plunkr - http://plnkr.co/edit/VfISHNULXRLe52NeAsn1?p=preview

* Musisz zastąpić istniejący NG-app z odroczonym bootstrap

fragment kodu -

angular.element(document).ready(function() { 
    deferredBootstrapper.bootstrap({ 
     element: document.body, 
     module: 'plunker', 
     resolve: { 
      schema: ['$http', 
       function($http) { 
        return $http.get('schema.json'); 
       } 
      ] 
     } 
    }); 
}); 

Następnie można użyć schematu w każdym razie w kontrolerze , usługi lub fabryka, podobnie jak przy ustalaniu trasy.

Przykładowy kod dla Fabryki

app.factory('SomeService', function(schema){ 
    return { 
     getTitle: function() { 
      return schema.title; 
     } 
    } 
}); 
+0

Dokładnie to, czego szukałem, dzięki - odroczone ładowanie działa jak urok z tym komponentem! – conceptdeluxe