AngularJS + RequireJS - 未知提供者,角错误?
我收到了以下例外'未知的提供者:authSvc',它来源于我的config.js文件,我将在下面发表。我明白这个错误意味着我的authSvc模块没有被注册并且不可用,但是在我尝试注入之前创建了该服务。有人可以帮帮我吗?我迷失在这一个......所以我以为我会转向SO。谢谢。AngularJS + RequireJS - 未知提供者,角错误?
的index.html
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<!-- Place favicon.ico in the root directory -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
<!-- <script src="js/vendor/modernizr-2.8.3.min.js"></script> -->
<script data-main="js/main" src="js/vendor/require.js"></script>
</head>
<body>
<!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<nav class="navbar navbar-inverse navbar-fixed-top" ng-controller="navCtrl">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><button class="btn btn-default navbar-btn" ng-click="login()">Login</button></li>
<li><button class="btn btn-info navbar-btn" ng-click="register()">Register</button></li>
</ul>
</div><!--/.navbar-collapse -->
</div>
</nav>
<div ng-view></div>
</body>
</html>
main.js
require.config({
paths: {
'angular': 'vendor/angular',
'domReady': 'vendor/domready',
'angularRoute': 'vendor/angular-route',
'angularLocalStorage': 'vendor/angular-local-storage',
'bootstrapCss': 'vendor/bootstrap-css'
},
shim: {
'angular': {
exports: 'angular'
},
'angularRoute': {
deps: ['angular']
},
'angularLocalStorage': {
deps: ['angular']
}
},
deps: ['./bootstrap']
});
bootstrap.js
require([
'angular',
'app',
'services/authSvc',
'controllers/navCtrl',
'controllers/landingPageCtrl',
'controllers/homeCtrl',
'controllers/loginCtrl',
'config',
'routes'
], function (angular) {
'use strict';
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
});
app.js
define([
'angular',
'angularRoute',
'angularLocalStorage'
], function(angular, angularRoute, angularLocalStorage) {
'use strict';
var app = angular.module('myApp', ['ngRoute', 'LocalStorageModule']);
return app;
});
authSvc.js
define(['app'], function(app) {
app.service('authSvc', function($http, localStorageService) {
this.setToken = function(token) {
return localStorageService.set('token', token);
}
this.getToken = function() {
return localStorageService.get('token');
}
this.login = function(username, password) {
return $http.post('/api/login', {username: username, password: password});
}
});
console.log('authSvc registered');
});
config.js
define(['app'], function(app) {
'use strict';
app.config(function($httpProvider, authSvc) {
$httpProvider.interceptors.push(function($q) {
return {
'request': function(config) {
// same as above
//config.headers.token = authSvc.getToken();
return config;
},
'response': function(response) {
// same as above
return response;
}
};
});
});
console.log('config registered');
});
不能在配置块注射服务。只有提供者。
app
.factory('yourInterceptor', yourInterceptor)
.config(configureInterceptor);
function configureInterceptor($httpProvider) {
$httpProvider.interceptors.push('yourInterceptor');
}
function yourInterceptor(authSvc) {
return {
'request': function (config) {
// same as above
//config.headers.token = authSvc.getToken();
return config;
},
'response': function (response) {
// same as above
return response;
}
};
}
编辑:
通注射到你的拦截,并得到使用注射器
function yourInterceptor($injector) {
return {
'request': function (config) {
var authService = $injector.get('authSvc');
//config.headers.token = authSvc.getToken();
return config;
},
'response': function (response) {
// same as above
return response;
}
};
}
因此,如果我有一个服务从本地存储获取身份验证令牌,那么如何将该服务注入app.config()内的http拦截器?谢谢。 –
我想唯一的解决方案是不使用app.service('authSvc',...)? –
我会尝试一下你在编辑中的方式,如果它有效,我会将它标记为答案。 –
服务实例如果任何人都可以帮帮忙,我的项目是完全停顿,直到我可以排序了这一点。我检查了我的控制台的网络面板,并且按照它们在bootstrap.js中的顺序加载,这意味着在使用注入的服务调用.config()之前正在创建服务。没有任何意义,它是投掷未知提供程序 –
更新:一直在修补,注意到authSvc工作正常时,注入一个控制器,例如navCtrl,只是抛出未知的提供程序时注入.config()。这是一个错误? –