Angular JS неизвестный поставщик


152

Я пытаюсь "настроить" пример mongolab под мой собственный REST API. Теперь я сталкиваюсь с этой ошибкой, и я не уверен, что я делаю неправильно:

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)

Это мой контроллер:

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

и это модуль:

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

      return Product;
    }]);

Эта ошибка указывает на то, что angular не знает о фабрике продукта, убедитесь, что JS для этой службы в первую очередь является справочным. Также при объявлении модулей убедитесь, что явно определены зависимости, потому что, когда файлы свернуты, эта ошибка также возникнет из-за искажения имени. Для получения дополнительной информации, смотрите эту статью :: ozkary.com/2015/11/…
ozkary

Ответы:


130

Ваш код выглядит хорошо, фактически он работает (кроме самих вызовов), когда копируется и вставляется в пример jsFiddle: http://jsfiddle.net/VGaWD/

Трудно сказать, что происходит, не видя более полного примера, но я надеюсь, что приведенный выше jsFiddle будет полезен. Я подозреваю, что вы не инициализируете свое приложение с помощью модуля «productServices» . Это даст ту же ошибку, мы можем увидеть это в другом jsFiddle: http://jsfiddle.net/a69nX/1/

Если вы планируете работать с AngularJS и MongoLab, я бы предложил использовать существующий адаптер для $ resource и MongoLab : https://github.com/pkozlowski-opensource/angularjs-mongolab. Это облегчает большую часть работы с MongoLab. можете увидеть это в действии здесь: http://jsfiddle.net/pkozlowski_opensource/DP4Rh/ Отказ от ответственности! Я поддерживаю этот адаптер (написан на основе примеров AngularJS), поэтому я явно предвзят.


У меня та же проблема, и это не решило мою проблему. Я на самом деле получаю данные обратно ... За исключением этого сообщения об ошибке, вы думаете, что все работает просто отлично. Я не использую ng-app в элементе body, но загружаюсь так: angular.element (document) .ready (function () {angular.bootstrap (document, ['reportServices']);});
Том

17
Привет, ребята, это немного стыдно. У меня точно такая же проблема. Но я не могу определить разницу между двумя jsFiddles. Любая подсказка о том, где именно искать, очень ценится.
Schacki

4
@schacki, разницу в скрипках можно найти на информационной вкладке. У одного из них есть тело, <body ng-app="productServices">а у другого есть <body ng-app="">.
Вине Рейнольдс

А где информационная вкладка? :)
Алекс

3
Похоже, что информационная вкладка теперь является Fiddle Optionsвкладкой справа
Gangstead

40

Я получил эту ошибку, потому что передавал неверный параметр в определение фабрики. Я имел:

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

Это сработало, когда я удалил $scopeи изменил определение фабрики на:

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

Если вам нужно ввести $scope, используйте:

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

32

У меня просто была похожая проблема. Ошибка сказала то же самое в вопросе, попытался решить ее с помощью ответов pkozlowski.opensource и Ben G, которые оба являются правильными и хорошими ответами.

Моя проблема действительно отличалась с той же ошибкой:

в моем HTML-коде у меня была такая инициализация ...

<html ng-app>

Чуть дальше я попытался сделать что-то вроде этого:

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

Я избавился от первого ... потом это сработало ... очевидно, вы не можете инициализировать ng-app дважды или более раз. справедливо.

Я полностью забыл о первом "ng-app" и полностью разочаровался. Может быть, это поможет кому-то в один день ...


2
У меня была похожая проблема, но в моем случае наличие ng-controller, указанного в div, было причиной для контроллера, который ссылается на сервис. Кажется, что Angular не знал, как разрешить службу, когда он анализировал представление.
Гектор Корреа

25

Убедитесь, что ваш основной app.jsвключает в себя услуги, от которых он зависит. Например:

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

1
Если я не ошибаюсь, в таком случае productServicesдолжен быть модуль, поэтому не имеет значения, что находится внутри такого модуля (сервис или нет).
Гринольдман

17

Ответ Пкозловского верен, но на случай, если это случится с кем-то другим, у меня возникла та же ошибка после создания одного и того же модуля дважды по ошибке; второе определение переопределяло поставщика первого:

Я создал модуль, выполнив

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

затем немного дальше в том же файле:

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

Правильный способ сделать это:

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

11

В моем случае я определил нового поставщика, скажем, xyz

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

Когда вы настраивали вышеуказанного провайдера, вы должны добавить его с Providerдобавленной строкой -> xyzстановится xyzProvider.

Пример:

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

Если вы введете вышеуказанного провайдера без строки «Провайдер», вы получите аналогичную ошибку в OP.


8

В конце файла JS закрыть заводскую функцию у меня было

});

вместо того

}());


1
Для моего проекта мы обычно используем})();
mrOak

5

Это заняло у меня слишком много времени, чтобы выследить. Убедитесь, что вы минизащитите свой контроллер в пределах своей директивы.

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

  return {

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

    }]
  }
}

надеюсь, это поможет


5

Чтобы добавить сюда свой собственный опыт, я пытался внедрить службу в одну из функций конфигурации моего модуля. Этот параграф из документов, которые я в конце концов нашел, объясняет, почему это не работает:

Во время начальной загрузки приложения, прежде чем Angular завершит создание всех служб, он настраивает и создает экземпляры всех поставщиков. Мы называем это этапом настройки жизненного цикла приложения. На этом этапе службы недоступны, поскольку они еще не созданы.

Это означает, что вы можете внедрить провайдеров в функции module.config (...), но вы не можете внедрить сервисы, для этого вам нужно подождать, пока module.run (...), или выставить провайдера, которого вы можете внедрить в модуль. конфиг


4

Для меня эта ошибка была вызвана запуском уменьшенной версии моего углового приложения. Угловые документы предлагают способ обойти это. Вот соответствующая цитата, описывающая проблему, и вы можете найти предлагаемое решение в самих документах здесь :

Замечание о минимизации Поскольку Angular выводит зависимости контроллера из имен аргументов в функцию-конструктор контроллера, если бы вы минимизировали код JavaScript для контроллера PhoneListCtrl, все его аргументы функции также были бы минимизированы, а инжектор зависимости не будет быть в состоянии правильно идентифицировать услуги.


3

Так как это лучший результат для "неизвестного поставщика angularjs" в Google прямо сейчас, вот еще одна ошибка. Выполняя модульное тестирование с Jasmine, убедитесь, что в вашей beforeEach()функции есть следующее утверждение :

module('moduleName'); 

В противном случае вы получите ту же ошибку в ваших тестах.


3

Еще один случай, когда эта ошибка произойдет, если ваша служба определена в отдельном файле javascript, убедитесь, что вы ссылаетесь на нее! Да, я знаю, ошибка новичка.


2

Я забыл ввести файл, содержащий мои услуги вообще. Не забудьте сделать это при инициализации модуля приложения:

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

2

В моем случае я использовал анонимную функцию в качестве оболочки для углового модуля, например:

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

После закрытия скобок я забыл вызвать анонимную функцию, открыв и закрыв скобки снова, как указано выше.


я знаю, что ты ответил на это 4 года назад, но это помогло мне сегодня, спасибо.
Леголас

1

Для меня проблема была в ленивой загрузке; Я загрузил свой контроллер и сервис поздно, поэтому они не были доступны при загрузке страницы (и угловой инициализации). Я сделал это с помощью тега UI-If, но это не имеет значения. Решением было загрузить сервис с уже загруженной страницей.


1

Вот еще один возможный сценарий, где вы можете увидеть эту ошибку:

Если вы используете Sublime Text 2 и угловой плагин, он будет генерировать заглушки, как это

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

        }
    }
]);

обратите внимание на пустой '' как первый элемент массива после строки 'utilFactory'. Если у вас нет никаких зависимостей, удалите это так:

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

        }
    }
]);

1

Поскольку этот вопрос является лучшим результатом Google, я добавлю еще одну возможную вещь в список.

Если в используемом модуле произошел сбой в оболочке внедрения зависимостей, он даст такой же результат. Например, модули копирования и вставки из Интернета могут полагаться на underscore.js и пытаться добавить «_» в оболочку di. Если в поставщиках зависимостей вашего проекта нет подчеркивания, когда ваш контроллер попытается обратиться к фабрике вашего модуля, он получит «неизвестного поставщика» для вашей фабрики в журнале консоли браузера.


1

Проблема для меня заключалась в том, что я создал несколько новых файлов javascript, которые ссылались на сервис, но Chrome видел только старую версию. CTRL + F5 исправил это для меня.


0

Я получил ошибку «неизвестный поставщик», связанную с angular-mocks (ngMockE2E) при компиляции моего проекта с Grunt. Проблема была в том, что angular-mocks нельзя минимизировать, поэтому мне пришлось удалить его из списка минимизированных файлов.


0

После обработки с этой ошибкой, я могу поддержать этот список ответов с моим собственным делом.

В то же время это просто и глупо (возможно, не глупо для начинающих, как я, но да для экспертов), ссылка на скрипт на angular.min.js должна быть первой в вашем списке скриптов на html-странице.

Это работает:

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

Это не:

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

Обратите внимание на angular.min.js.

Надеюсь, это кому-нибудь поможет !! :)


0

Моя проблема была с Йоманом, используя (с большой буквы):

yo angular:factory Test

Сделанные файлы (некапитализированные):

app/scripts/services/test.js

но файл index.html включен (с большой буквы):

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

Надеюсь, это кому-нибудь поможет.


0

Еще одна возможность.

У меня было unknown Provider <- <- nameOfMyService. Ошибка была вызвана следующим синтаксисом:

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

Angular искал ''зависимость.


Ошибка: [$ injector: unpr] Неизвестный поставщик: LoginFactoryProvider <- LoginFactory У меня есть этот файл, так как я могу это исправить
ninjaXnado

0

Мой сценарий может быть немного неясным, но он может вызвать ту же ошибку, и кто-то может испытать ее, поэтому:

При использовании службы $ controller для создания экземпляра нового контроллера (который ожидал '$ scope' в качестве первого введенного аргумента) я передавал локальную область действия нового контроллера во второй параметр функции $ controller (). Это привело к тому, что Angular попытался вызвать службу $ scope, которая не существует ( хотя некоторое время я действительно думал, что каким-то образом удалил службу $ scope из кеша Angular ). Решение состоит в том, чтобы обернуть локальную область видимости в объект localals:

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

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

0

Ни один из приведенных выше ответов для меня не сработал, возможно, я поступил совершенно неправильно, но мы, как новичок, делаем то же самое.

Я инициализировал контроллер divв, чтобы получить список:

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

А затем использовать $routeProviderдля сопоставления URL на тот же контроллер. Как только я убрал ng-initконтроллер работал с маршрутом.


0

У меня была такая же проблема. Я исправил это, используя $('body').attr("ng-app", 'MyApp')вместо <body ng-app="MyApp">boostrap.

Потому что я сделал

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

для архитектурных требований.


0

В своем приложении Ruby on Rails я сделал следующее:

rake assets:precompile

Это было сделано в среде разработки, которая уменьшила Angular.js и включила его в /public/assets/application.jsфайл.

Удаление /public/assets/*файлов решило проблему для меня.


0

Я столкнулся с подобной проблемой сегодня, и проблемы были действительно очень маленькими

 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);
            }
        }
    }
}
});

Если вы наблюдаете вышеупомянутый блок, в первой строке вы увидите, что я ввел $ scope по ошибке, что неверно. Я удалил эту нежелательную зависимость, чтобы решить проблему.

 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

У меня была эта ошибка после того, как я создал новую фабрику и использовал ее в компоненте, но я не проверял спецификации этих компонентов

так что если ошибка в ваших (спецификации) тестовых файлов

вам нужно добавить beforeEach(module('YouNewServiceModule'));


-1

Еще одно замечание: я получаю эту ошибку, вводя $ timeout, и потребовалось несколько минут, чтобы понять, что у меня есть пробелы в значениях массива. Это не будет работать:

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

Публикация на случай, если у кого-то еще есть глупая ошибка, подобная этой.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.