кутовий js невідомий постачальник


152

Я намагаюся "налаштувати" приклад монголабу, щоб він відповідав моєму власному API REST. Зараз я стикаюся з цією помилкою, і я не впевнений, що я роблю неправильно:

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

Ця помилка вказує на те, що кутовий не знає про фабрику виробу, переконайтеся, що JS для цієї послуги спочатку має посилання. Також при оголошенні модулів обов'язково чітко визначайте залежності, оскільки при мінімізації файлів ця помилка також з’явиться через керування назвою. Для отримання додаткової інформації дивіться цю статтю :: ozkary.com/2015/11/…
ozkary

Відповіді:


130

Ваш код виглядає добре, адже він працює (крім самих дзвінків), коли копіюється та вставляється у зразок jsFiddle: http://jsfiddle.net/VGaWD/

Важко сказати, що відбувається, не бачачи більш повного прикладу, але сподіваюся, що вищевказаний jsFiddle буде корисним. Я підозрюю, що ви не ініціалізуєте свій додаток модулем "productServices" . Це призведе до тієї ж помилки, ми можемо побачити це в іншій jsFiddle: http://jsfiddle.net/a69nX/1/

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


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

17
Привіт, хлопці, це трохи неприємно. У мене точно така ж проблема. Але я не можу помітити різницю між 2 jsFiddles. Будь-який натяк на те, де саме слід шукати, високо цінуємо.
schacki

4
@schacki, Різницю у загадках можна знайти на інформаційній вкладці. Один з них має тіло, <body ng-app="productServices">а інший - <body ng-app="">.
Vineet Reynolds

А де вкладка інформації? :)
Алекс

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-додаток двічі чи більше разів. досить справедливо.

Я загалом забув про перше "ng-додаток" і розчарувався. Можливо, це допоможе комусь одного дня ...


2
У мене була аналогічна проблема, але в моєму випадку вказання ng-контролера, вказаного в діві, було винуватцем контролера, який посилається на службу. Здається, що Angular не знав, як вирішити послугу, коли вона розібрала подання.
Гектор Кореа

25

Переконайтеся, що ваша основна app.jsвключає послуги, від яких це залежить. Наприклад:

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

1
Якщо я не помиляюся, у такому випадку productServicesповинен бути модуль, тому не має значення, що знаходиться всередині такого модуля (послуги чи ні).
greenoldman

17

Відповідь pkozlowski правильна, але про всяк випадок, якщо це трапилося з кимось іншим, у мене була одна і та ж помилка після створення одного і того ж модуля двічі помилково; друге визначення переважало постачальника першого:

Я створив модуль, виконавши

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

Якщо ви введете вищевказаного постачальника без рядка "Провайдер", ви отримаєте аналогічну помилку в ОП.


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 зараз, ось ще одна єва. Виконуючи тестування блоку з Жасмином, переконайтеся, що у вас є ця заява у своїй 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 та спробувати ввести його у "обгортку". Якщо підкреслення не існує у ваших постачальників залежностей від проекту, коли ваш контролер намагається посилатись на заводський модуль, він отримає "невідомий постачальник" для вашої фабрики в журналі консолі браузера.


1

Проблема для мене полягала в тому, що я створив нові файли javascript, які посилаються на сервіс, але Chrome бачив лише старішу версію. CTRL + F5 зафіксував це для мене.


0

Під час компіляції мого проекту з Grunt я отримав помилку "невідомого постачальника", пов’язану з кутовими макетами (ngMockE2E). Проблема полягала в тому, що кутові макети неможливо змінити, тому мені довелося видалити його зі списку мінімізованих файлів.


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

Моя проблема була з Yeoman, використовуючи (з великої літери):

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() { ... }]);

Кутовий шукав ''залежність.


Помилка: [$ injector: unpr] Невідомий постачальник: LoginFactoryProvider <- LoginFactory Я знаю цього, тож як я можу це виправити
ninjaXnado

0

Мій сценарій може бути дещо незрозумілим, але він може спричинити ту ж помилку, і хтось може зіткнутися з ним, так:

Під час використання послуги контролера $ для створення екземпляра нового контролера (який очікував "$ range", оскільки він вперше був введений аргумент), я передавав локальний діапазон нового контролера у другий параметр функції $ controller (). Це призвело до того, що Angular намагається викликати послугу $ range, яка не існує ( хоча, на деякий час, я дійсно думав, що я би дещо видалив службу '$ range' з кешу Angular ). Рішення полягає в тому, щоб обернути локальну область в об'єкт місцевих жителів:

// 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">.

Тому що я

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

для архітектурних вимог.


0

У своєму додатку Ruby on Rails я зробив наступне:

rake assets:precompile

Це було зроблено в середовищі "development", яке змістило 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);
            }
        }
    }
}
});

Якщо ви дотримуєтесь вищезазначеного блоку, у першому рядку ви помітите, що я ввів $ range помилково, що невірно. Я усунув цю небажану залежність, щоб вирішити проблему.

 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

Ще один "gotcha": я отримував цю помилку, вводивши $ timeout, і пішло кілька хвилин, щоб зрозуміти, що у значенні масиву є пробіл. Це не вийде:

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

Публікація про всяк випадок, якщо хтось інший має помилкову помилку, як це.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.