Chcę wprowadzić usługę do pliku app.config, aby można było pobrać dane przed wywołaniem kontrolera. Spróbowałem tak:
Usługa:
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
Konfiguracja:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
Ale pojawia się ten błąd:
Błąd: nieznany dostawca: dbService z EditorApp
Jak poprawić konfigurację i wstrzyknąć tę usługę?
Odpowiedzi:
Alex podał prawidłowy powód, dla którego nie możesz zrobić tego, co próbujesz zrobić, więc +1. Ale napotykasz ten problem, ponieważ nie do końca używasz rozwiązań, w jaki sposób są zaprojektowane.
resolve
pobiera ciąg usługi lub funkcję zwracającą wartość do wstrzyknięcia. Ponieważ robisz to drugie, musisz przekazać rzeczywistą funkcję:Kiedy framework zostanie rozwiązany
data
, wstrzyknie elementdbService
do funkcji, dzięki czemu możesz go swobodnie używać. Nie musisz w ogóle wstrzykiwać doconfig
bloku, aby to osiągnąć.Smacznego!
źródło
.service
, więc ruszaj$q
i$http
tam.pageData: 'myData'
, ale wtedy musiałbyś zadzwonićpageData.overview
ze swojego kontrolera. Metoda string jest prawdopodobnie użyteczna tylko wtedy, gdy fabryka usług zwróciła obietnicę zamiast interfejsu API. Tak więc sposób, w jaki obecnie to robisz, jest prawdopodobnie najlepszym sposobem.Skonfiguruj usługę jako niestandardowego dostawcę AngularJS
Pomimo tego, co mówi Zaakceptowana odpowiedź, w rzeczywistości MOŻESZ zrobić to, co zamierzałeś zrobić, ale musisz ustawić go jako konfigurowalnego dostawcę, aby był dostępny jako usługa na etapie konfiguracji. Najpierw zmień
Service
dostawcę na dostawcę jak pokazano niżej. Kluczowa różnica polega na tym, że po ustawieniu wartościdefer
ustawia siędefer.promise
właściwość na obiekt obietnicy zwracany przez$http.get
:Usługa dostawcy: (dostawca: przepis na usługę)
Teraz masz konfigurowalnego dostawcę niestandardowego, wystarczy go wstrzyknąć. Kluczowa różnica polega na tym, że brakujący „Dostawca na Twoim wstrzykiwaczu”.
config:
użyj rozwiązanych danych w swoim
appCtrl
Możliwe alternatywy
Poniższa alternatywa jest podobnym podejściem, ale umożliwia definicję w ramach
.config
, hermetyzowanie usługi do określonego modułu w kontekście aplikacji. Wybierz odpowiednią dla siebie metodę. Zobacz także poniżej uwagi na temat trzeciej alternatywy i pomocnych linków, które pomogą Ci zrozumieć te wszystkie rzeczyKilka pomocnych zasobów
$http
konkretną w kontekście tej prośbyfactory
/service
/ .provider
Dostawca zapewnia nieco większą konfigurację w stosunku do
.service
metody, co czyni go lepszym jako dostawca na poziomie aplikacji, ale możesz również hermetyzować to w samym obiekcie konfiguracyjnym, wstrzykując$provide
do konfiguracji w następujący sposób:źródło
$get
połączenia. Zamiast tego chcesz dodać metody do wystąpienia dostawcy i po prostu powrócićthis
podczas wywołania$get
. W rzeczywistości w twoim przykładzie możesz po prostu użyć usługi ... W dostawcy nie możesz również wstrzyknąć usług takich jak$http
. A przy okazji są to//return the factory as a provider, that is available during the configuration phase
mylące / niepoprawne informacjeKrótka odpowiedź: nie możesz. AngularJS nie pozwoli ci wstrzyknąć usług do konfiguracji, ponieważ nie może być pewien, że zostały poprawnie załadowane.
Zobacz to pytanie i odpowiedź: Wstrzyknięcie wartości w zależności od AngularJS wewnątrz module.config
źródło
Nie sądzę, abyś był w stanie to zrobić, ale pomyślnie wstrzyknąłem usługę do
config
bloku. (AngularJS v1.0.7)źródło
.config
napisałeś cacheBuster (który nie jest zdefiniowany nigdzie w odpowiedzi) i dogmaCacheBusterProvider (który nie jest dalej używany). Czy możesz to wyjaśnić?cacheBuster
jest zdefiniowany jako parametr funkcji config. Jeśli chodzi odogmaCacheBusterProvider
to, to coś sprytnego, co Angular robi z konwencjami nazewnictwa, o których dawno zapomniałem. To może Cię przybliżyć, stackoverflow.com/a/20881705/110010 ..provider()
przepisie. co jeśli zdefiniuję coś za pomocą.factory('ServiceName')
lub.service('ServiceName')
Receptę i chcę użyć jednej z jej metod w.config
bloku, ustaw parametr jako ServiceNameProvider, ale zatrzyma moją aplikację.Możesz użyć usługi $ inject, aby wstrzyknąć usługę w swojej konfiguracji
Źródło: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
** Wyraźnie żądaj usług z innych modułów za pomocą angular.injector **
Aby rozwinąć odpowiedź kim3er , możesz świadczyć usługi, fabryki itp. Bez zmiany ich na dostawców, o ile są one zawarte w innych modułach ...
Nie jestem jednak pewien, czy
*Provider
(który jest wykonany wewnętrznie przez angular po przetworzeniu usługi lub fabryki) zawsze będzie dostępny (może zależeć od tego, co jeszcze zostanie załadowane jako pierwsze), ponieważ angular leniwie ładuje moduły.Zwróć uwagę, że jeśli chcesz ponownie wstrzyknąć wartości, powinny być traktowane jako stałe.
Oto bardziej wyraźny i prawdopodobnie bardziej niezawodny sposób na zrobienie tego + działający plunker
źródło
Używanie $ injector do wywoływania metod serwisowych w config
Miałem podobny problem i rozwiązałem go za pomocą usługi $ injector, jak pokazano powyżej. Próbowałem bezpośrednio wstrzyknąć usługę, ale skończyło się na cyklicznej zależności od $ http. Usługa wyświetla modal z błędem i używam modalu ui-bootstrap, który również ma zależność od $ https.
źródło
Rozwiązanie bardzo łatwe do zrobienia
Uwaga : jest to tylko dla wywołania asynchronicznego, ponieważ usługa nie jest inicjowana podczas wykonywania konfiguracji.
Możesz użyć
run()
metody. Przykład:Twój kod :
źródło
Cóż, trochę się zmagałem z tym, ale faktycznie to zrobiłem.
Nie wiem, czy odpowiedzi są nieaktualne z powodu jakiejś zmiany kąta, ale możesz to zrobić w ten sposób:
To jest twoja usługa:
A to jest config
źródło
Najprostszy sposób:
$injector = angular.element(document.body).injector()
Następnie użyj tego do uruchomienia
invoke()
lubget()
źródło