AngularJS错误:$injector:unpr未知提供者。

64

我正试图通过遵循工厂方法的文档示例来构建自己的服务。然而,我认为我做错了什么,因为我持续收到“未知提供程序”错误。这是我的应用程序代码,包括声明、配置和工厂定义。

编辑

我现在已经添加了所有文件以帮助排除故障。

编辑

错误的完整细节如下,问题似乎出在getSettings上,因为它正在寻找getSettingsProvider却找不到。

Error: [$injector:unpr] http://errors.angularjs.org/1.2.16/$injector/unpr?    p0=getSettingsProvider%20%3C-%20getSettings
    at Error (native)
    at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:6:450
    at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:35:431
    at Object.c [as get] (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:13)
    at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:35:499
    at c (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:13)
    at d (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:230)
    at Object.instantiate (http://localhost/sw/selfservice/bower_components/angular/angular.min.js:34:394)
    at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:66:112
    at http://localhost/sw/selfservice/bower_components/angular/angular.min.js:53:14 angular.js:9778
(anonymous function) angular.js:9778
(anonymous function) angular.js:7216
h.$apply angular.js:12512
(anonymous function) angular.js:1382
d angular.js:3869
$b.c angular.js:1380
$b angular.js:1394
Wc angular.js:1307
(anonymous function) angular.js:21459
a angular.js:2509
(anonymous function) angular.js:2780
q angular.js:330
c



这些是我目前在我的应用程序中拥有的所有文件

app.JS

//Initialize angular module include route dependencies

var app = angular.module("selfservice", ['ngRoute']);

app.config(function ($routeProvider) {
   $routeProvider
       .when('/', {
           templateUrl:"partials/login.html",
           controller:"login"
       });
});






app.factory('getSettings', ['$http', '$q', function($http, $q) {
    return function (type) {
        var q = $q.defer();
        $http.get('models/settings.json').success(function (data) {
            q.resolve(function() {
                var settings = jQuery.parseJSON(data);
                return settings[type];
            });
        });

        return q.promise;
    };
}]);

这是我在控制器中使用该服务的方法:

controller.JS

app.controller("globalControl", ['$scope','getSettings', function ($scope,getSettings) {
    var loadSettings = getSettings('global');
    loadSettings.then(function(val) {
        $scope.settings = val;
    });

}]);


app.controller("login", ['$scope', function ($scope) {

    return ""



}]);

指令.js

app.directive('watchResize', function(){
    return {
        restrict: 'M',
        link: function(scope, elem, attr) {
            scope.spacer = (window.innerWidth < 1025) ? '' : 'large-3';
            scope.button = (window.innerWidth < 1025) ? '' : 'large-6';
            angular.element(window).on('resize', function(){
                scope.$apply(function(){
                    scope.spacer = (window.innerWidth < 1025) ? '' : 'large-3';
                    scope.button = (window.innerWidth < 1025) ? '' : 'large-6';
                });
            });
        }
    };
});

如果这里相关的话,这就是HTML

<html class="no-js" lang="en" ng-app="selfservice" ng-controller="globalControl">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>{{settings.title}}</title>
     <link rel="stylesheet" href="css/app.css" />
    <script src="bower_components/modernizr/modernizr.js"></script>
      <script src="bower_components/angular/angular.min.js"></script>
       <script src="bower_components/angular-route/angular-route.min.js"></script>
       <script src="bower_components/jquery/dist/jquery.min.js"></script>
      <script src="js/app.js"></script>
      <script src="js/controllers.js"></script>
      <script src="js/directives.js"></script>
  </head>
  <body>
    <div id="template">
        <header id="header">
            <img src="{{settings.logo}}" alt="{{settings.logoDescription}}"/>
        </header>

        <div id="view">
            <ng-view></ng-view>
        </div>

    </div>

    <script src="bower_components/foundation/js/foundation.min.js"></script>
        <script>
        //initialize foundation
        $(document).foundation();

    </script>
  </body>
</html>

有人可以指点我正确的方向吗?我已经尽力按照文档进行操作,查看了相关问题,但大部分都很深入且难以理解。这是我第一次创建服务。


1
错误是否提供了未知提供者的名称?通常错误中会有一个字符串值。 - Ben Felda
1
在控制台中,您应该能够单击未知提供程序错误消息,这将带您到一个Angular页面,为您提供有关错误的更多信息。将此信息发布在您的问题中可能会有所帮助。 - Josh Beam
抱歉一开始没有提供所有的细节,我想让问题简明扼要,但是现在我已经提供了我所知道的有关问题的所有细节。 - richbai90
你能标记一下问题是否已解决吗? - julio
1
对于任何遇到这个问题的人(首先在Google中),我在类似问题的答案中找到了解决方法:https://dev59.com/7YLba4cB1Zd3GeqPcUiZ#25193243 - JVG
13个回答

47

另一个常见原因可能是您忘记在页面中包含服务文件。

<script src="myservice.js"></script>

6
谢谢!因为这个问题,我调试了好几个小时。 - vishalmullur
4
一个小时的冲浪成果,拿去吧。愚蠢的错误。谢谢。 - rohanagarwal
1
当你意识到你忘记在捆绑包中包含文件时,这是那种让人摇头的时刻。 - Dermo909

34
您的angular模块需要正确初始化。全局对象app需要被定义并正确初始化,以注入服务。
请参考下面的示例代码:
app.js
var app = angular.module('SampleApp',['ngRoute']); //You can inject the dependencies within the square bracket    

app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
  $routeProvider
    .when('/', {
      templateUrl:"partials/login.html",
      controller:"login"
    });

  $locationProvider
    .html5Mode(true);
}]);

app.factory('getSettings', ['$http', '$q', function($http, $q) {
  return {
    //Code edited to create a function as when you require service it returns object by default so you can't return function directly. That's what understand...
    getSetting: function (type) { 
      var q = $q.defer();
      $http.get('models/settings.json').success(function (data) {
        q.resolve(function() {
          var settings = jQuery.parseJSON(data);
          return settings[type];
        });
      });
      return q.promise;
    }
  }
}]);

app.controller("globalControl", ['$scope','getSettings', function ($scope,getSettings) {
  //Modified the function call for updated service
  var loadSettings = getSettings.getSetting('global');
  loadSettings.then(function(val) {
    $scope.settings = val;
  });
}]);

示例HTML代码应该像这样:

<!DOCTYPE html>
<html>
    <head lang="en">
        <title>Sample Application</title>
    </head>
    <body ng-app="SampleApp" ng-controller="globalControl">
        <div>
            Your UI elements go here
        </div>
        <script src="app.js"></script>
    </body>
</html>

请注意,控制器绑定的不是HTML标签而是body标签。此外,请尝试在HTML页面末尾包含自定义脚本,因为这是遵循性能原则的标准做法。
希望这能解决您的基本注入问题。

2
我看不出你在示例中做了什么,而我在这个问题中已经展示了,你能具体说明一下吗? - richbai90
2
我已经更新了答案并添加了适当的注释。希望这能解决您的问题。 - Kunal Shewale
谢谢,你救了我,我花了12个小时搜索,问题是在app.configfunction之间缺少['$routeProvider', - Hibatallah Aouadni

10
app.factory('getSettings', ['$http','$q' /*here!!!*/,function($http, $q) {

你需要声明所有依赖项或者都不声明,你忘记声明 $q。

编辑:

controller.js:login,不要返回“”


我看到我错过了那个地方,所以我更新了我的代码来包括它,但仍然出现相同的错误。我已经更新了问题以更好地查看我的所有代码。 - richbai90
你把app.js、directive.js和service.js的内容都放进去了吗?因为我猜不出这些文件里面是什么。 - mpm
我已经添加了所有的文件。 - richbai90

9

当某人错误地将$scope注入到他们的工厂中时,也会出现此错误:

angular.module('m', [])
    .factory('util', function ($scope) { // <-- this '$scope' gives 'Unknown provider' when one attempts to inject 'util'
       // ...
    });

这个非常有帮助。 - Daniël Camps

3
花了几个小时尝试解决同样的问题。这是我做的方式:
app.js:
var myApp = angular.module( 'myApp', ['ngRoute', 'ngResource', 'CustomServices'] );

CustomServices是我创建的一个新模块,放在名为services.js的单独文件中。
_Layout.cshtml:
<script src="~/Scripts/app.js"></script>
<script src="~/Scripts/services/services.js"></script>

services.js:

var app = angular.module('CustomServices', []); 
app.factory( 'GetPeopleList', ['$http', '$log','$q', function ( $http, $log, $q )
{
    //Your code here
}

app.js

myApp.controller( 'mainController', ['$scope', '$http', '$route', '$routeParams', '$location', 'GetPeopleList', function ( $scope, $http, $route, $routeParams, $location, GetPeopleList )

你需要在services.js文件中将你的服务绑定到新模块上,当然你还需要在创建主应用程序模块(app.js)时使用该新模块,并且在想要使用它的控制器中声明使用该服务。

2
我遇到了这个问题,后来发现我在ui.router和html模板中都引入了我的控制器,如下所示:
.config(['$stateProvider',
  function($stateProvider) {
    $stateProvider.state('dashboard', {
      url: '/dashboard',
      templateUrl: 'dashboard/views/index.html',
      controller: 'DashboardController'
    });
  }
]);

and

<section data-ng-controller="DashboardController">

1
请同时“包含”控制器和调用控制器中函数的模块。
module(theModule);

0
请确保您在app.config之外加载控制器。以下代码可能会导致此错误:
app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
       var AuthCtrl = require('components/auth/AuthCtrl'); //NOTICE HERE
       $stateProvider.state('login',{
            url: "/users/login",
            templateUrl: require("components/auth/login.tpl.html"),
            controller: AuthCtrl // ERROR
        })
}))

为了解决这个错误,我们必须将AuthCtrl移动到app.config
var AuthCtrl = require('components/auth/AuthCtrl'); //NOTICE HERE
app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
       $stateProvider.state('login',{
            url: "/users/login",
            templateUrl: require("components/auth/login.tpl.html"),
            controller: AuthCtrl // WORK
        });
}))

0

@ user2310334 我刚刚尝试了一个非常基本的例子:

HTML文件

<!DOCTYPE html>
<html lang="en" ng-app="app">

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-route.min.js" type="text/javascript"></script>
    <script src="./app.js" type="text/javascript"></script>
</head>

<body>
    <div ng-controller="MailDetailCtrl">
    </div>
</body>
</html>

JavaScript文件:

var myApp= angular.module('app', ['ngRoute']);

myApp.factory('mailService' , function () {
return {
    getData : function(){
      var employees = [{name: 'John Doe', id: '1'},
        {name: 'Mary Homes', id: '2'},
        {name: 'Chris Karl', id: '3'}
      ];

      return employees;
    }
  };

});


myApp.controller('MailDetailCtrl',['$scope', 'mailService', function($scope, mailService) {
  alert(mailService.getData()[0].name);
}]);

它可以正常工作。试试看。


0

由于这是在搜索 Error: $injector:unpr Unknown Provider 时在 Google 上首先出现的第一个 Stackoverflow 问题,我会在这里添加。

请确保在您的 index.html 中,任何模块/依赖项在需要它们之后不会被加载。

例如,在我的代码中,customFactory.factory.js 如下所示:

angular
   .module("app.module1")
   .factory("customFactory", customFactory);

然而,index.html看起来像这样:

    <script src="/src/client/app/customFactory.factory.js"></script>
    <script src="/src/client/app/module1.module.js"></script>

它实际上应该看起来像这样:

    <script src="/src/client/app/module1.module.js"></script>
    <script src="/src/client/app/customFactory.factory.js"></script>

由于customFactory.factory.js是作为module1的一部分声明的,它需要在customFactory之前被加载。


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