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

Answers:


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

17
大家好,这有点尴尬。我也有完全一样的问题。但是我无法发现2个jsFiddles之间的区别。非常感谢您提供有关在何处准确查找的任何提示。
schacki 2013年

4
@schacki,小提琴的不同之处可以在信息选项卡中找到。其中一个具有身体,<body ng-app="productServices">另一个具有<body ng-app="">
Vineet Reynolds

信息标签在哪里?:)
Aleks

3
看起来信息选项卡现在Fiddle Options是右侧的选项卡
Gangstead 2014年

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在解析视图时不知道如何解析服务。
赫克托·科雷亚

25

确保您的主系统app.js包括它所依赖的服务。例如:

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

1
如果我没记错的话,在这种情况下productServices应该是一个模块,因此与该模块内部的内容(服务与否)无关。
greenoldman '16

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

如果注入上面的提供程序而没有'Provider'字符串,则会在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文档建议了一种解决此问题的方法。这里所描述的问题相关的报价,你可以找到自己的文档建议的解决方案在这里

关于缩小的说明由于Angular从参数名称推断出控制器的依赖关系到控制器的构造函数,因此,如果要缩小PhoneListCtrl控制器的JavaScript代码,则其所有函数参数也将被缩小,而依赖项注入器将不会能够正确识别服务。


3

由于这是目前Google上“ angularjs未知提供程序”的最高结果,因此这是另一个陷阱。使用Jasmine进行单元测试时,请确保beforeEach()函数中包含以下语句:

module('moduleName'); 

否则,您将在测试中得到同样的错误。


3

如果您的服务是在单独的javascript文件中定义的,那么还会发生此错误的另一种情况,请确保引用它!是的,我知道,菜鸟的错误。


2

我忘记了注入完全保存我的服务的文件。请记住在初始化应用程序模块时执行以下操作:

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

2

就我而言,我使用了一个匿名函数作为angular模块的包装器,如下所示:

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

关闭括号后,我忘了如上所述再次通过打开和关闭括号来调用匿名函数。


我知道你4年前回答了,但是今天对我有帮助,谢谢。
莱戈拉斯

1

对我来说,问题是延迟加载;我晚些时候加载了控制器和服务,因此页面加载(和Angular初始化)时它们不可用。我使用ui-if标记执行此操作,但这无关紧要。解决方案是使用页面加载功能来加载服务。


1

在另一种可能的情况下,您会看到此错误:

如果您使用Sublime Text 2和angular插件,它将生成像这样的存根

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

使用Grunt编译我的项目时,出现了一个与angular-mocks(ngMockE2E)有关的“未知提供程序”错误。问题是无法减小角mo,因此我不得不将其从缩小文件列表中删除。


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

Angular正在寻找''依赖关系。


错误:[$ injector:unpr]未知提供程序:LoginFactoryProvider <-LoginFactory我已经解决了这个问题,所以我该如何解决这个问题
ninjaXnado

0

我的场景可能有点晦涩,但是可能导致相同的错误,并且有人可能会遇到,所以:

当使用$ controller服务实例化一个新的控制器时(它期望它是第一个注入的参数“ $ scope”),我正在将新控制器的本地作用域传递给$ controller()函数的第二个参数。这导致Angular试图调用一个不存在的$ scope服务(尽管有一段时间,我实际上以为我会从Angular的缓存中删除'$ scope'服务)。解决方案是将本地范围包装在locals对象中:

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

发布以防万一其他人有这样的愚蠢错误。


-2

我的情况是狡猾的打字

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

函数有一个“ c”!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.