angular js nieznany dostawca


152

Próbuję „dostosować” przykład mongolabu, aby pasował do mojego własnego interfejsu API REST. Teraz napotykam ten błąd i nie jestem pewien, co robię źle:

Error: Unknown provider: ProductProvider <- Product
    at Error (unknown source)
    at http://localhost:3000/js/vendor/angular.min.js:28:395
    at Object.c [as get] (http://localhost:3000/js/vendor/angular.min.js:26:180)
    at http://localhost:3000/js/vendor/angular.min.js:28:476
    at c (http://localhost:3000/js/vendor/angular.min.js:26:180)
    at d (http://localhost:3000/js/vendor/angular.min.js:26:314)

To jest mój kontroler:

function ProductListCtrl($scope, Product) {
  $scope.products = Product.query();
}

a to jest moduł:

angular.module('productServices', ['ngResource']).
    factory('Product', ['$resource', function($resource){
      var Product = $resource('/api/products/:id', {  }, {
        update: { method: 'PUT' }
      });

      return Product;
    }]);

Ten błąd oznacza, że ​​firma Angular nie wie o fabryce produktu, upewnij się, że JS dla tej usługi jest pierwszym punktem odniesienia. Również podczas deklarowania modułów upewnij się, że jawnie zdefiniowałeś zależności, ponieważ gdy pliki są zminimalizowane, ten błąd również wystąpiłby z powodu zniekształcenia nazwy. Aby uzyskać więcej informacji, spójrz na ten artykuł :: ozkary.com/2015/11/…
ozkary

Odpowiedzi:


130

Twój kod wygląda dobrze, w rzeczywistości działa (oprócz samych wywołań) po skopiowaniu i wklejeniu do przykładowego pliku jsFiddle: http://jsfiddle.net/VGaWD/

Trudno powiedzieć, co się dzieje, nie widząc pełniejszego przykładu, ale mam nadzieję, że powyższy jsFiddle będzie pomocny. Podejrzewam, że nie inicjujesz aplikacji za pomocą modułu „productServices” . Dałby ten sam błąd, widzimy to w innym jsFiddle: http://jsfiddle.net/a69nX/1/

Jeśli planujesz pracować z AngularJS i MongoLab , sugerowałbym użycie istniejącego adaptera dla zasobu $ i MongoLab : https://github.com/pkozlowski-opensource/angularjs-mongolab Zmniejsza wiele bólu podczas pracy z MongoLab, można zobaczyć to w akcji tutaj: http://jsfiddle.net/pkozlowski_opensource/DP4Rh/ Disclaimer! Utrzymuję ten adapter (napisany na podstawie przykładów AngularJS), więc jestem tutaj oczywiście stronniczy.


Mam ten sam problem i to nie rozwiązało mojego problemu. Właściwie odzyskuję dane ... Oprócz tego komunikatu o błędzie można by pomyśleć, że wszystko działa dobrze. Nie używam jednak ng-app w elemencie body, ładuję w ten sposób: angular.element (dokument) .ready (function () {angular.bootstrap (dokument, ['reportServices']);});
Tom

17
Cześć, to trochę zawstydzające. Mam dokładnie ten sam problem. Ale nie mogę dostrzec różnicy między 2 jsFiddles. Każda wskazówka, gdzie dokładnie szukać, jest bardzo cenna.
schacki

4
@schacki, Różnicę w skrzypcach można znaleźć w zakładce info. Jeden z nich ma ciało, <body ng-app="productServices">a drugi ma <body ng-app="">.
Vineet Reynolds

A gdzie jest zakładka informacyjna? :)
Aleks

3
Wygląda na to, że zakładka informacyjna jest teraz Fiddle Optionszakładką po prawej
Gangstead,

40

Otrzymałem ten błąd, ponieważ przekazywałem nieprawidłowy parametr do definicji fabrycznej. Miałem:

myModule.factory('myService', function($scope, $http)...

Zadziałało, gdy usunąłem $scopei zmieniłem definicję fabryki na:

myModule.factory('myService', function( $http)...

W przypadku konieczności wstrzyknięcia $scopeużyj:

myModule.factory('myService', function($rootScope, $http)...

32

Właśnie miałem podobny problem. Błąd powiedział to samo w pytaniu, próbowałem go rozwiązać za pomocą odpowiedzi pkozlowski.opensource i Ben G, które są poprawne i dobre.

Mój problem był rzeczywiście inny z tym samym błędem:

w moim kodzie HTML miałem taką inicjalizację ...

<html ng-app>

Nieco dalej próbowałem zrobić coś takiego:

<div id="cartView" ng-app="myApp" ng-controller="CartCtrl">

Pozbyłem się pierwszego ... wtedy zadziałało ... oczywiście nie możesz inicjalizować ng-app dwa lub więcej razy. Słusznie.

Całkowicie zapomniałem o pierwszej "ng-aplikacji" i byłem totalnie sfrustrowany. Może to kiedyś komuś pomoże ...


2
Miałem podobny problem, ale w moim przypadku posiadanie ng-kontrolera określonego w div było winowajcą kontrolera, który odwołuje się do usługi. Wygląda na to, że Angular nie wiedział, jak rozwiązać usługę, gdy przeanalizował widok.
Hector Correa

25

Upewnij się, że twój main app.jszawiera usługi, od których zależy. Na przykład:

/* App Module */
angular.module('myApp', ['productServices']). 
.....

1
Jeśli się nie mylę to w takim przypadku productServicespowinien to być moduł, więc nie ma znaczenia, co jest w środku takiego modułu (usługi czy nie).
greenoldman

17

odpowiedź pkozłowskiego jest poprawna, ale na wypadek, gdyby zdarzyło się to komuś innemu, miałem ten sam błąd po dwukrotnym utworzeniu tego samego modułu przez pomyłkę; druga definicja unieważnia dostawcę pierwszej:

Stworzyłem moduł wykonując

angular.module('MyService'...
).factory(...);

potem nieco dalej w tym samym pliku:

angular.module('MyService'...
).value('version','0.1');

Prawidłowy sposób to:

angular.module('MyService'...
).factory(...).value('version','0.1');

11

W moim przypadku zdefiniowałem nowego dostawcę, powiedzmy xyz

angular.module('test')
.provider('xyz', function () {
    ....
});

Kiedy miałeś skonfigurować powyższego dostawcę, musisz wstrzyknąć go z Providerdołączonym ciągiem -> xyzstaje się xyzProvider.

Dawny:

angular.module('App', ['test'])
.config(function (xyzProvider) {
     // do something with xyzProvider....
});

Jeśli wstrzykniesz powyższego dostawcę bez ciągu „Provider”, otrzymasz podobny błąd w OP.


8

Na końcu pliku JS, aby zamknąć funkcję fabryczną, którą miałem

});

zamiast

}());


1
W moim projekcie zwykle używamy})();
mrOak

5

Wytropienie tego zajęło mi zbyt dużo czasu. Upewnij się, że minimalizujesz bezpieczeństwo kontrolera w ramach dyrektywy.

.directive('my_directive', ['injected_item', function (injected_item){

  return {

    controller: ['DO_IT_HERE_TOO', function(DO_IT_HERE_TOO){

    }]
  }
}

Mam nadzieję, że to pomoże


5

Aby dodać tutaj własne doświadczenie, próbowałem wstrzyknąć usługę do jednej z moich funkcji konfiguracyjnych modułu. Ten akapit z dokumentów, które w końcu znalazłem, wyjaśnia, dlaczego to nie działa:

Podczas ładowania aplikacji, zanim Angular rozpocznie tworzenie wszystkich usług, konfiguruje i tworzy instancje wszystkich dostawców. Nazywamy to fazą konfiguracji cyklu życia aplikacji. Na tym etapie usługi nie są dostępne, ponieważ nie zostały jeszcze utworzone.

Oznacza to, że możesz wstrzyknąć dostawców do funkcji module.config (...), ale nie możesz wstrzyknąć usług, w tym celu musisz poczekać, aż module.run (...), lub ujawnić dostawcę, którego możesz wstrzyknąć do modułu. config


4

U mnie ten błąd był spowodowany uruchomieniem zminimalizowanej wersji mojej aplikacji kątowej. Doktorzy Angular sugerują sposób obejścia tego problemu. Oto odpowiedni cytat opisujący problem, a sugerowane rozwiązanie można znaleźć w samych dokumentach tutaj :

Uwaga na temat minifikacji Ponieważ Angular wnioskuje zależności kontrolera z nazw argumentów do funkcji konstruktora kontrolera, gdybyś zminimalizował kod JavaScript dla kontrolera PhoneListCtrl, wszystkie jego argumenty funkcji również zostałyby zminimalizowane, a iniektor zależności nie. być w stanie poprawnie zidentyfikować usługi.


3

Ponieważ jest to obecnie najwyższy wynik dla „nieznanego dostawcy angularjs” w Google, oto kolejny problem. Wykonując testy jednostkowe z Jasmine, upewnij się, że masz w beforeEach()funkcji następującą instrukcję :

module('moduleName'); 

W przeciwnym razie w testach wystąpi ten sam błąd.


3

Jeszcze inny przypadek, w którym wystąpi ten błąd, jeśli Twoja usługa jest zdefiniowana w oddzielnym pliku javascript, upewnij się, że odwołujesz się do niego! Tak, wiem, błąd debiutanta.


2

Zapomniałem wstrzyknąć plik, który całkowicie zawierał moje usługi. Pamiętaj, aby zrobić to podczas inicjowania modułu aplikacji:

angular.module('myApp', ['myApp.services', ... ]);

2

W moim przypadku użyłem anonimowej funkcji jako otoki dla modułu kątowego, na przykład:

(function () {
var app = angular.module('myModule', []);
...
})();

Po zamknięciu nawiasów zapomniałem wywołać funkcję anonimową, otwierając i ponownie zamykając nawiasy, jak powyżej.


Wiem, że odpowiedziałeś na to 4 lata temu, ale pomogło mi to dzisiaj, dzięki.
Legolas

1

Dla mnie problemem było leniwe ładowanie; Późno załadowałem kontroler i usługę, więc nie były one dostępne podczas ładowania strony (i inicjalizacji Angular). Zrobiłem to z tagiem ui-if, ale to nie ma znaczenia. Rozwiązaniem było załadowanie usługi już z załadowaną stroną.


1

Oto kolejny możliwy scenariusz, w którym można zobaczyć ten błąd:

Jeśli używasz Sublime Text 2 i wtyczki kątowej, wygeneruje ona takie kody pośredniczące

angular.module('utils', [])
.factory('utilFactory', [''
    function() {
        return {

        }
    }
]);

zwróć uwagę na pusty „” jako pierwszy element tablicy po ciągu „utilFactory”. Jeśli nie masz żadnych zależności, usuń to, aby wyglądało tak:

angular.module('utils', [])
.factory('utilFactory', [
    function() {
        return {

        }
    }
]);

1

Ponieważ to pytanie jest najlepszym wynikiem w Google, dodam do listy kolejną możliwą rzecz.

Jeśli moduł, którego używasz, ma błąd w otoce iniekcji zależności, zapewni ten sam wynik. Na przykład moduły kopiowania i wklejania z Internetu mogą polegać na underscore.js i próbować wstrzyknąć znak „_” w opakowaniu di. Jeśli podkreślenie nie istnieje w dostawcach zależności projektu, gdy kontroler spróbuje odwołać się do fabryki modułu, otrzyma „nieznanego dostawcę” dla fabryki w dzienniku konsoli przeglądarki.


1

Problem polegał na tym, że utworzyłem kilka nowych plików javascript, które odwoływały się do usługi, ale Chrome widział tylko starszą wersję. CTRL + F5 naprawił to za mnie.


0

Podczas kompilowania projektu za pomocą Grunt wystąpił błąd „nieznanego dostawcy” związany z makietami kątowymi (ngMockE2E). Problem polegał na tym, że makiety kątowe nie mogły zostać zminimalizowane, więc musiałem usunąć je z listy zminimalizowanych plików.


0

Po rozwiązaniu tego błędu również mogę wesprzeć tę listę odpowiedzi w mojej własnej sprawie.

Jest to jednocześnie proste i głupie (może nie głupie dla początkujących jak ja, ale tak dla ekspertów), odniesienie do skryptu angular.min.js musi być pierwszym na liście skryptów na stronie html.

To działa:

<script src="Scripts/angular.min.js"></script>
<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>

To nie:

<script src="MyScripts/MyCartController.js"></script>
<script src="MyScripts/MyShoppingModule.js"></script>
<script src="Scripts/angular.min.js"></script>

Uwaga dotycząca pliku angular.min.js.

Mam nadzieję, że to pomoże każdemu! :)


0

Mój problem dotyczył Yeoman, używając (pisane wielkimi literami):

yo angular:factory Test

Wykonane pliki (bez wielkich liter):

app/scripts/services/test.js

ale dołączony plik index.html (pisany wielkimi literami):

<script src="scripts/services/Test.js"></script>

Mam nadzieję, że to komuś pomoże.


0

Jeszcze inna możliwość.

Miałem unknown Provider <- <- nameOfMyService. Błąd został spowodowany następującą składnią:

module.factory(['', function() { ... }]);

Angular szukał ''zależności.


Błąd: [$ injector: unpr] Nieznany dostawca: LoginFactoryProvider <- LoginFactory mam to, więc jak mogę to naprawić
ninjaXnado

0

Mój scenariusz może być trochę niejasny, ale może powodować ten sam błąd i ktoś może go doświadczyć, więc:

Podczas korzystania z usługi $ controller do tworzenia instancji nowego kontrolera (który oczekiwał „$ scope” jako pierwszego wstrzykniętego argumentu) przekazywałem lokalny zakres nowego kontrolera do drugiego parametru funkcji $ controller (). To doprowadziło do tego, że Angular próbował wywołać usługę $ scope, która nie istnieje ( chociaż przez chwilę myślałem, że w jakiś sposób usunę usługę '$ scope' z pamięci podręcznej Angulara ). Rozwiązaniem jest zawinięcie zakresu lokalnego w obiekt lokalny:

// Bad:
$controller('myController', newScope);

// Good:
$controller('myController, {$scope: newScope});

0

Żadna z powyższych odpowiedzi nie zadziałała dla mnie, może robiłem zupełnie źle, ale jako początkujący tak właśnie robimy.

Inicjalizowałem kontroler divw celu uzyskania listy:

 <div ng-controller="CategoryController" ng-init="initialize()">

A następnie użycie $routeProviderdo mapowania adresu URL na ten sam kontroler. Jak tylko zdjąłem ng-initkontroler działał z trasą.


0

Miałem ten sam problem. Naprawiłem to używając $('body').attr("ng-app", 'MyApp')zamiast<body ng-app="MyApp"> Boostrap.

Ponieważ to zrobiłem

angular.element(document).ready(function () {        
    angular.bootstrap(document, [App.Config.Settings.AppName]);
})

do wymagań architektonicznych.


0

W mojej aplikacji Ruby on Rails wykonałem następujące czynności:

rake assets:precompile

Zrobiono to w środowisku „programistycznym”, które zminimalizowało Angular.js i włączyło go do /public/assets/application.jspliku.

Usunięcie /public/assets/*plików rozwiązało problem za mnie.


0

Zmierzyłem się dzisiaj z podobnym problemem i problemy były naprawdę bardzo małe

 app.directive('removeFriend', function($scope) {
return {
    restrict: 'E',
    templateUrl: 'removeFriend.html',
    controller: function($scope) {
        $scope.removing = false;
        $scope.startRemove = function() {
            $scope.removing = true;
        }
        $scope.cancelRemove = function() {
            $scope.removing = false;
        }
        $scope.removeFriend = function(friend) {
            var idx = $scope.user.friends.indexOf(friend)
            if (idx > -1) {
                $scope.user.friends.splice(idx, 1);
            }
        }
    }
}
});

Jeśli zauważysz powyższy blok, w pierwszym wierszu zauważysz, że przez pomyłkę wstrzyknąłem $ scope, co jest niepoprawne. Usunąłem tę niechcianą zależność, aby rozwiązać problem.

 app.directive('removeFriend', function() {
return {
    restrict: 'E',
    templateUrl: 'removeFriend.html',
    controller: function($scope) {
        $scope.removing = false;
        $scope.startRemove = function() {
            $scope.removing = true;
        }
        $scope.cancelRemove = function() {
            $scope.removing = false;
        }
        $scope.removeFriend = function(friend) {
            var idx = $scope.user.friends.indexOf(friend)
            if (idx > -1) {
                $scope.user.friends.splice(idx, 1);
            }
        }
    }
}
});

0

Miałem ten błąd po utworzeniu nowej fabryki i zastosowaniu jej w komponencie, ale nie sprawdziłem specyfikacji tych komponentów

więc jeśli błąd w plikach testowych (specyfikacji)

musisz dodać beforeEach(module('YouNewServiceModule'));


-1

Kolejna „łapanka”: otrzymywałem ten błąd podczas wstrzykiwania $ timeout i zajęło mi kilka minut, zanim zdałem sobie sprawę, że w wartościach tablicy mam białe znaki. To nie zadziała:

angular.module('myapp',[].
  controller('myCtrl', ['$scope', '$timeout ', 
    function ($scope, $timeout){
      //controller logic
    }
  ]);

Publikowanie na wypadek, gdyby ktoś inny miał taki głupi błąd.


-2

Mój przypadek był podejrzany

myApp.factory('Notify',funtion(){

funkcja ma „c”!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.