在app.config中注入服务

我想在app.config中注入一个服务,以便在调用控制器之前可以检索数据。 我试过这样的:

服务:

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; } }; }); 

configuration:

 app.config(function ($routeProvider, dbService) { $routeProvider .when('/', { templateUrl: "partials/editor.html", controller: "AppCtrl", resolve: { data: dbService.getData(), } }) }); 

但是我得到这个错误:

错误:来自EditorApp的未知提供者:dbService

如何纠正设置并注入此服务?

亚历克斯提供了正确的理由不能做你想做的事情,所以+1。 但是你遇到了这个问题,因为你不能解决它们是如何devise的。

resolve方法是将服务的string或返回值的函数注入。 既然你在做后者,你需要传递一个实际的函数:

 resolve: { data: function (dbService) { return dbService.getData(); } } 

当框架去parsingdata ,它会将dbService注入到函数中,以便您可以自由使用它。 你根本不需要注入config块来完成这个任务。

好胃口!

将您的服务设置为自定义的AngularJS提供程序

尽pipe接受的答案说,你实际上可以做你打算做的事情,但你需要设置它作为一个可configuration的提供商,以便它在configuration阶段作为服务提供。首先,将您的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; }) } } 

现在,你有一个可configuration的自定义提供程序,你只需要注入它。 这里的主要区别是缺less“注射剂供应商”。

configuration:

 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使用parsing的数据

 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); } }) 

可能的select

下面的替代方法是类似的方法,但允许定义在.config发生,将服务封装在应用上下文中的特定模块中。 select适合您的方法。 另请参阅下面的备注和有用的链接,以帮助您掌握所有这些事情

 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分钟的解释和演示,这是免费的课程之一! 我基本上修改了他的演示,使其在这个请求的上下文中具有特定的$http
  • 查看供应商的AngularJS开发者指南
  • 在clevertech.biz也有关于factory / service / provider的很好的解释。

提供程序通过.service方法提供了更多的configuration,这使得它更适合作为应用程序级别的提供者,但是您也可以通过在configuration中注入$provide来像这样将其封装在configuration对象中:

简短的回答:你不能。 AngularJS将不允许你注入服务到configuration中,因为它不能确定它们已经被正确加载了。

看到这个问题和答案: AngularJSdependency injectionmodule.config中的值

模块是在引导过程中应用于应用程序的configuration和运行块的集合。 最简单的forms是模块由两种块的集合组成:

configuration块 – 在提供程序注册和configuration阶段执行。 只有提供者和常量可以注入到configuration块中。 这是为了防止在完全configuration之前意外地实例化服务。

我不认为你应该能够做到这一点,但我已经成功地将一个服务注入config块。 (AngularJS v1.0.7)

 angular.module('dogmaService', []) .factory('dogmaCacheBuster', [ function() { return function(path) { return path + '?_=' + Date.now(); }; } ]); angular.module('touch', [ 'dogmaForm', 'dogmaValidate', 'dogmaPresentation', 'dogmaController', 'dogmaService', ]) .config([ '$routeProvider', 'dogmaCacheBusterProvider', function($routeProvider, cacheBuster) { var bust = cacheBuster.$get[0](); $routeProvider .when('/', { templateUrl: bust('touch/customer'), controller: 'CustomerCtrl' }) .when('/screen2', { templateUrl: bust('touch/screen2'), controller: 'Screen2Ctrl' }) .otherwise({ redirectTo: bust('/') }); } ]); angular.module('dogmaController', []) .controller('CustomerCtrl', [ '$scope', '$http', '$location', 'dogmaCacheBuster', function($scope, $http, $location, cacheBuster) { $scope.submit = function() { $.ajax({ url: cacheBuster('/customers'), //server script to process data type: 'POST', //Ajax events // Form data data: formData, //Options to tell JQuery not to process data or worry about content-type cache: false, contentType: false, processData: false, success: function() { $location .path('/screen2'); $scope.$$phase || $scope.$apply(); } }); }; } ]); 

您可以使用$ inject服务在您的config中注入一个服务

的app.config(函数($提供){

     $ provide.decorator(“$ exceptionHandler”,function($ delegate,$ injector){
        返回函数(exception,原因){
             var $ rootScope = $ injector.get(“$ rootScope”);
             $ rootScope.addError({message:“Exception”,reason:exception});
             $委托(exception,原因);
         };
     });

 });

资料来源: http : //odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx

使用anuglar.injector从其他模块显式请求服务

只要详细说明kim3er的答案 ,只要它们包含在其他模块中,就可以提供服务,工厂等,而不必将其更改为提供者。

但是,我不确定是否*Provider (在处理服务或工厂之后通过angular度内部生成)始终可用(可能取决于首先加载的其他内容),因为angular度延迟加载模块。

请注意,如果你想重新注入他们应该被视为常量的值

这是一个更明确,可能更可靠的方式来做到这一点+ 一个工作的重击者

 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(); }); 

使用$ injector来调用config中的服务方法

我有一个类似的问题,并通过使用$注射器服务解决它,如上所示。 我尝试直接注入服务,但结束了对$ http的循环依赖。 该服务显示错误的模式,我正在使用ui-bootstrap模式,它也依赖于$ 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.") } } } 

一个解决scheme很容易做到这一点

注意 :这只适用于asynchronous调用,因为服务在configuration执行时没有被初始化。

你可以使用run()方法。 例如:

  1. 您的服务被称为“我的服务”
  2. 你想使用它在提供程序“MyProvider”上执行asynchronous执行

你的代码:

 (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; }]); }); 

最简单的方法: $injector = angular.element(document.body).injector()

然后用它来运行invoke()get()

好吧,我用这个挣了一点,但是我真的做到了。

我不知道由于angular度的变化,答案是否过时,但你可以这样做:

这是你的服务:

 .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; } }; }); 

这是configuration

 .when('/beer-detail', { templateUrl : '/beer-detail', controller : 'productDetailController', resolve: { beer: function(beerRetrievalService) { return beerRetrievalService.getRandomBeer(); } } })