Angularjs 在app.config中注入服务
我想在app.config中插入一个服务,以便在调用控制器之前检索数据。我这样试过: 服务:Angularjs 在app.config中注入服务,angularjs,Angularjs,我想在app.config中插入一个服务,以便在调用控制器之前检索数据。我这样试过: 服务: app.service('dbService', function() { return { getData: function($q, $http) { var defer = $q.defer(); $http.get('db.php/score/getData').success(function(data) {
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
配置:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
但我得到了这个错误:
错误:未知提供程序:来自EditorApp的dbService
如何更正设置并注入此服务?简短回答:您不能。AngularJS不允许您将服务注入配置中,因为它无法确保这些服务已正确加载 请参见此问题和答案: 模块是配置和运行块的集合,这些块 在引导过程中应用于应用程序。在其 最简单的形式模块由两类块的集合组成: 配置块-在提供商注册和配置阶段执行。仅提供程序和常量 可以注入到配置块中。这是为了防止 在服务完全启动之前意外实例化服务 配置
Alex提供了无法执行您尝试执行的操作的正确原因,因此+1。但您遇到这个问题是因为您没有完全使用解决方案来解决它们的设计方式
resolve
获取服务字符串或返回要注入值的函数。由于您正在执行后者,因此需要传入一个实际函数:
解析:{
数据:功能(dbService){
返回dbService.getData();
}
}
当框架开始解析数据时
,它会将dbService
注入函数,以便您可以自由使用它。您根本不需要注入config
块来完成此操作
祝你胃口好 我不认为您应该能够做到这一点,但我已经成功地将服务注入到
config
块中。(AngularJS v1.0.7)
将您的服务设置为自定义AngularJS提供商
不管公认的答案是什么,您实际上可以执行您打算执行的操作,但您需要将其设置为可配置的提供者,以便在配置阶段将其作为服务提供。。首先,将您的服务更改为提供商,如下所示。这里的关键区别在于,在设置了defer
的值之后,您将defer.promise
属性设置为$http.get
返回的promise对象:
提供者服务:(提供者:服务配方)
现在,您有了一个可配置的自定义提供程序,只需注入它。这里的关键区别在于缺少“您的可注射剂上的提供者”
配置:
在appCtrl
可能的替代方案
以下替代方法与此类似,但允许在.config
中进行定义,将服务封装到应用程序上下文中的特定模块中。选择适合你的方法。另请参阅下面关于第三种选择的注释和帮助您掌握所有这些技巧的有用链接
app.config(function($routeProvider, $provide) {
$provide.service('dbService',function(){})
//set up your service inside the module's config.
$routeProvider
.when('/', {
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data:
}
})
});
一些有用的资源
- 约翰·林德奎斯特(John Lindquist)在上有一个精彩的5分钟解释和演示,这是免费的课程之一!我基本上修改了他的演示,在这个请求的上下文中指定了
$http
- 在上查看AngularJS开发人员指南
- 还有一个关于
工厂
/服务
/提供商
的精彩解释
提供程序通过.service
方法为您提供了更多的配置,这使它作为应用程序级提供程序变得更好,但是,您也可以通过将$provide
注入config中,将其封装在config对象本身中,就像这样:**使用angular.injector显式地从其他模块请求服务**
仅详细说明一下,您可以提供服务、工厂等,而无需将它们更改为提供商,只要它们包含在其他模块中
但是,由于angular延迟加载模块,我不确定*提供程序
(由angular在处理服务或工厂后在内部创建)是否始终可用(可能取决于首先加载的其他内容)
请注意,如果要重新注入值,则应将其视为常量
这里有一种更明确、更可靠的方法
使用$injector调用配置中的服务方法
我有一个类似的问题,并通过使用$injector服务解决了它,如上所示。我尝试直接注入服务,但最终在$http上产生了循环依赖。该服务显示一个带有错误的模式,我使用的是ui引导模式,它也依赖于$https
$httpProvider.interceptors.push(function($injector) {
return {
"responseError": function(response) {
console.log("Error Response status: " + response.status);
if (response.status === 0) {
var myService= $injector.get("myService");
myService.showError("An unexpected error occurred. Please refresh the page.")
}
}
}
解决方案非常简单
注意:它仅用于异步调用,因为服务在配置执行时未初始化
您可以使用run()
方法。例如:
您的服务称为“MyService”
您希望将其用于提供程序“MyProvider”上的异步执行
您的代码:
(function () { //To isolate code TO NEVER HAVE A GLOBAL VARIABLE!
//Store your service into an internal variable
//It's an internal variable because you have wrapped this code with a (function () { --- })();
var theServiceToInject = null;
//Declare your application
var myApp = angular.module("MyApplication", []);
//Set configuration
myApp.config(['MyProvider', function (MyProvider) {
MyProvider.callMyMethod(function () {
theServiceToInject.methodOnService();
});
}]);
//When application is initialized inject your service
myApp.run(['MyService', function (MyService) {
theServiceToInject = MyService;
}]);
});
您可以使用$inject service在配置中插入服务
app.config(function($provide){
$provide.decorator("$exceptionHandler", function($delegate, $injector){
return function(exception, cause){
var $rootScope = $injector.get("$rootScope");
$rootScope.addError({message:"Exception", reason:exception});
$delegate(exception, cause);
};
});
});
app.config(函数($provide){
$Provider.decorator($exceptionHandler),函数($delegate,$injector){
返回函数(异常、原因){
var$rootScope=$injector.get($rootScope”);
$rootScope.addError({消息:“异常”,原因:异常});
$delegate(例外情况、原因);
};
});
});
来源:最简单的方法:
$injector=angular.element(document.body).injector()
然后用它来运行invoke()
或get()
好吧,我有点费劲,但实际上我做到了
我不知道答案是否因为角度的变化而过时了,但你可以这样做
app.config(function($routeProvider, $provide) {
$provide.service('dbService',function(){})
//set up your service inside the module's config.
$routeProvider
.when('/', {
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data:
}
})
});
var base = angular.module('myAppBaseModule', [])
base.factory('Foo', function() {
console.log("Foo");
var Foo = function(name) { this.name = name; };
Foo.prototype.hello = function() {
return "Hello from factory instance " + this.name;
}
return Foo;
})
base.service('serviceFoo', function() {
this.hello = function() {
return "Service says hello";
}
return this;
});
var app = angular.module('appModule', []);
app.config(function($provide) {
var base = angular.injector(['myAppBaseModule']);
$provide.constant('Foo', base.get('Foo'));
$provide.constant('serviceFoo', base.get('serviceFoo'));
});
app.controller('appCtrl', function($scope, Foo, serviceFoo) {
$scope.appHello = (new Foo("app")).hello();
$scope.serviceHello = serviceFoo.hello();
});
$httpProvider.interceptors.push(function($injector) {
return {
"responseError": function(response) {
console.log("Error Response status: " + response.status);
if (response.status === 0) {
var myService= $injector.get("myService");
myService.showError("An unexpected error occurred. Please refresh the page.")
}
}
}
(function () { //To isolate code TO NEVER HAVE A GLOBAL VARIABLE!
//Store your service into an internal variable
//It's an internal variable because you have wrapped this code with a (function () { --- })();
var theServiceToInject = null;
//Declare your application
var myApp = angular.module("MyApplication", []);
//Set configuration
myApp.config(['MyProvider', function (MyProvider) {
MyProvider.callMyMethod(function () {
theServiceToInject.methodOnService();
});
}]);
//When application is initialized inject your service
myApp.run(['MyService', function (MyService) {
theServiceToInject = MyService;
}]);
});
app.config(function($provide){
$provide.decorator("$exceptionHandler", function($delegate, $injector){
return function(exception, cause){
var $rootScope = $injector.get("$rootScope");
$rootScope.addError({message:"Exception", reason:exception});
$delegate(exception, cause);
};
});
});
.factory('beerRetrievalService', function ($http, $q, $log) {
return {
getRandomBeer: function() {
var deferred = $q.defer();
var beer = {};
$http.post('beer-detail', {})
.then(function(response) {
beer.beerDetail = response.data;
},
function(err) {
$log.error('Error getting random beer', err);
deferred.reject({});
});
return deferred.promise;
}
};
});
.when('/beer-detail', {
templateUrl : '/beer-detail',
controller : 'productDetailController',
resolve: {
beer: function(beerRetrievalService) {
return beerRetrievalService.getRandomBeer();
}
}
})