AngularJS未知的提供者。

158

我试图将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。另外,在声明模块时,请确保明确定义依赖项,因为当文件被最小化时,由于名称混淆,也会出现此错误。有关更多信息,请参阅此文章:http://www.ozkary.com/2015/11/angularjs-minimized-file-unknown-provider.html - ozkary
你可能需要检查routes.js文件,以查看当前URL路径是否已在页面上加载了必要的提供程序。 - shasi kanth
30个回答

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示例编写),所以我显然有偏见。


我有同样的问题,这并没有解决我的问题。实际上,我确实收到了数据...除了这个错误消息,你会认为一切都正常工作。虽然我没有在body元素中使用ng-app,但我是这样引导的:angular.element(document).ready(function() { angular.bootstrap(document, ['reportServices']); }); - Tom
17
大家好,这有点尴尬。我也遇到了完全相同的问题。但是我无法发现这两个jsFiddles之间的区别。请问有什么提示可以帮我准确找到问题吗?非常感激。 - schacki
4
@schacki,在信息选项卡中可以找到小提琴之间的区别。其中一个带有 <body ng-app="productServices"> 的主体,另一个则为 <body ng-app=""> - Vineet Reynolds
1
信息选项卡在哪里? :) - Aleks
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
我遇到了类似的问题,但在我的情况下,在div中指定ng-controller是控制器引用服务的罪魁祸首。似乎当Angular解析视图时不知道如何解析服务。 - Hector Correa

28

确保您的主要app.js包含其所依赖的服务。例如:

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

1
如果我没记错的话,在这种情况下,productServices 应该是一个模块,因此该模块内部的内容(服务或其他)并不重要。 - greenoldman

18

pkozlowski的回答是正确的,但以防万一其他人也遇到同样的问题,我曾经因为错误地创建同一个模块两次而遇到了相同的错误;第二个定义将覆盖第一个的提供者:

我通过以下方式创建了该模块

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

然后在同一个文件中稍微往下一点:

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

正确的方法是:

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

12
在我的情况下,我定义了一个新的提供者,比如说,xyz
angular.module('test')
.provider('xyz', function () {
    ....
});
当您配置上述提供程序时,您需要注入带有附加的 Provider 字符串 --> xyz 变成 xyzProvider
示例:
angular.module('App', ['test'])
.config(function (xyzProvider) {
     // do something with xyzProvider....
});

如果您注入上述提供程序时没有使用“Provider”字符串,您将在 OP 中获得类似的错误。


8
在JS文件末尾关闭工厂函数时,我原本写成了:

});

而应该写成:

}());


1
对于我的项目,我们通常使用 })(); - mrOak

5
为了补充我的经验,我曾尝试在一个模块配置函数中注入一个服务。最终我找到的文档解释了为什么这不起作用:
在Angular创建所有服务之前,应用程序引导期间,它会配置和实例化所有提供程序。我们称之为应用程序生命周期的配置阶段。在此阶段,服务不可访问,因为它们尚未被创建。
这意味着您可以将提供程序注入到module.config(...)函数中,但无法注入服务,对于这个问题,您需要等到module.run(...),或者暴露一个提供程序,以便注入到module.config。

5

我花了很长时间才找到这个问题的解决方法。确保你在指令中对控制器进行最小化安全处理。

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

  return {

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

    }]
  }
}

希望这能帮到您。

4
对我来说,这个错误是由于运行我的angular应用程序的压缩版本引起的。Angular文档建议解决此问题的方法。以下是相关引用描述该问题,您可以在文档中找到建议的解决方案here
关于缩小的说明 由于Angular从控制器构造函数的参数名称推断出控制器的依赖项,因此,如果您要缩小PhoneListCtrl控制器的JavaScript代码,则所有函数参数也将被缩小,并且依赖项注入器将无法正确识别服务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接