我想将服务注入(inject)到app.config中,以便可以在调用 Controller 之前检索数据。我尝试过这样的:
服务:
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(),
}
})
});
但我收到此错误:
Error: Unknown provider: dbService from EditorApp
如何正确设置并注入(inject)此服务?
最佳答案
将您的服务设置为自定义 AngularJS 提供程序
尽管接受的答案是这样说的,您实际上可以做您想做的事情,但是您需要将其设置为可配置提供程序,以便在配置期间可以将其作为服务使用阶段.. 首先,将您的 Service
更改为提供商,如下所示。这里的关键区别在于,在设置了 defer 的值之后,将 defer.promise 属性设置为 $http.get 返回的 Promise 对象>:
提供商服务:(提供商:服务配方)
app.provider('dbService', function dbServiceProvider() {
//the provider recipe for services require you specify a $get function
this.$get= ['dbhost',function dbServiceFactory(dbhost){
// return the factory as a provider
// that is available during the configuration phase
return new DbService(dbhost);
}]
});
function DbService(dbhost){
var status;
this.setUrl = function(url){
dbhost = url;
}
this.getData = function($http) {
return $http.get(dbhost+'db.php/score/getData')
.success(function(data){
// handle any special stuff here, I would suggest the following:
status = 'ok';
status.data = data;
})
.error(function(message){
status = 'error';
status.message = message;
})
.then(function(){
// now we return an object with data or information about error
// for special handling inside your application configuration
return status;
})
}
}
现在,您已经有了一个可配置的自定义提供程序,您只需注入(inject)它即可。这里的主要区别是缺少“注入(inject)剂上的提供者”。
配置:
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
dbData: function(DbService, $http) {
/*
*dbServiceProvider returns a dbService instance to your app whenever
* needed, and this instance is setup internally with a promise,
* so you don't need to worry about $q and all that
*/
return DbService('http://dbhost.com').getData();
}
}
})
});
在 appCtrl
中使用已解析的数据
app.controller('appCtrl',function(dbData, DbService){
$scope.dbData = dbData;
// You can also create and use another instance of the dbService here...
// to do whatever you programmed it to do, by adding functions inside the
// constructor DbService(), the following assumes you added
// a rmUser(userObj) function in the factory
$scope.removeDbUser = function(user){
DbService.rmUser(user);
}
})
可能的替代方案
以下替代方法是类似的方法,但允许在 .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 在 egghead.io 对此做了 5 分钟的精彩解释和演示。 ,而且这是免费类(class)之一!我基本上修改了他的演示,使其
$http
在此请求的上下文中特定 - 查看 AngularJS 开发人员指南 Providers
- 还有关于
factory
/service
/provider
at clevertech.biz的精彩解释.
该提供程序为您提供了比 .service
方法更多的配置,这使得它作为应用程序级提供程序更好,但您也可以通过注入(inject) 将其封装在配置对象本身中$provide
进入配置,如下所示:
关于angularjs - 在app.config中注入(inject)服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15937267/