AngularJS错误:$ injector:unpr未知提供程序

时间:2014-05-29 20:27:47

标签: javascript angularjs angularjs-service

我正在尝试按照工厂方法文档中的示例构建自己的服务。我认为我做错了但是因为我继续得到未知的提供程序错误。这是我的应用程序代码,包括声明,配置和工厂定义。

修改 我现在已添加了所有文件以帮助排查

修改 错误的完整细节低于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 ""



}]);

directives.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>

有人能指出我正确的方向吗?我已尽力遵循文档,并查看大部分相关问题更深入,更难以理解。这是我第一次创建服务。

13 个答案:

答案 0 :(得分:38)

也是一个流行的原因,也许你错过了将服务文件包含在你的页面中

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

答案 1 :(得分:31)

您的角度模块需要正确初始化。需要正确定义和初始化全局对象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 :(得分:9)

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

你需要声明所有的依赖关系或者没有,你忘了声明$ q。

编辑:

controller.js:登录,不要返回&#34;&#34;

答案 3 :(得分:8)

当一个人意外地将$ scope注入他们的工厂时,也会出现此错误:

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

答案 4 :(得分: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)时使用该新模块并声明服务的使用在控制器中你想要使用它。

答案 5 :(得分:2)

我遇到了这个问题,事实证明我已将我的控制器包含在ui.router和html模板中,如

.config(['$stateProvider',
  function($stateProvider) {
    $stateProvider.state('dashboard', {
      url: '/dashboard',
      templateUrl: 'dashboard/views/index.html',
      controller: 'DashboardController'
    });
  }
]);

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

答案 6 :(得分:1)

请“包含”控制器和控制器中调用的控制器和功能所在的模块。

<h1>Title</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis laoreet scelerisque risus, eu scelerisque libero condimentum ut. Ut ac sapien placerat, suscipit odio vitae, vestibulum neque. Donec dui tortor, consequat rhoncus malesuada pharetra, dignissim
  sit amet mauris. Curabitur finibus arcu volutpat laoreet laoreet. Pellentesque mattis quam eget elit eleifend auctor. Fusce et nunc lobortis, laoreet leo sed, lacinia lorem. Nunc gravida eu eros et consequat.</p>
<div class="grad">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis laoreet scelerisque risus, eu scelerisque libero condimentum ut. Ut ac sapien placerat, suscipit odio vitae, vestibulum neque. Donec dui tortor, consequat rhoncus malesuada pharetra, dignissim
    sit amet mauris. Curabitur finibus arcu volutpat laoreet laoreet. Pellentesque mattis quam eget elit eleifend auctor. Fusce et nunc lobortis, laoreet leo sed, lacinia lorem. Nunc gravida eu eros et consequat.
  </p>
</div>
<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis laoreet scelerisque risus, eu scelerisque libero condimentum ut. Ut ac sapien placerat, suscipit odio vitae, vestibulum neque. Donec dui tortor, consequat rhoncus malesuada pharetra, dignissim
  sit amet mauris. Curabitur finibus arcu volutpat laoreet laoreet. Pellentesque mattis quam eget elit eleifend auctor. Fusce et nunc lobortis, laoreet leo sed, lacinia lorem. Nunc gravida eu eros et consequat.
</p>

答案 7 :(得分: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);
}]);

它有效。试试吧。

答案 8 :(得分: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
        });
}))

答案 9 :(得分:0)

就我而言,我在我的应用中添加了一项新服务(文件)。该新服务注入现有控制器。我没有错过对现有控制器的新服务依赖注入,并且没有声明我的app模块只有一个地方。当我重新运行我的网络应用程序并且我的浏览器缓存未重置并带有新的服务文件代码时,会抛出相同的异常。我只是刷新浏览器以获取浏览器缓存的新服务文件,问题就消失了。

答案 10 :(得分: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之前加载它

答案 11 :(得分:0)

我在编写Jasmine单元测试时遇到此错误。我有一行:

angular.injector(['myModule'])

它必须是:

angular.injector(['ng', 'myModule'])

答案 12 :(得分:-2)

当您使用ui-router时,不应在任何地方使用ng-controller。当激活适当的状态时,您的控制器将自动实例化为ui-view。