如何在angular度注入依赖到module.config(configFn)

在Angular中,我们可以将$routeProvider注入到config函数中

 module.config(function ($routeProvider) { }); 

我想像我一样注入我的服务

 module.config(function ($routeProvider, myService) { }); 

我确定这个服务是正确定义的,但是当我注入的时候会抛出一个exception,说明unknown myService事件

 module.config(function ($routeProvider, $http) { }); 

它仍然说unknown $http

你知道为什么吗?

从“ 模块”页面的“模块加载和相关性”部分:

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

运行块 – 在创build注入器后执行并用于启动应用程序。 只有实例和常量可以注入到运行块中。 这是为了防止应用程序运行时进一步的系统configuration。

所以你不能注入你自己的服务,或像$ http到config()的内置服务。 使用run()来代替。

我没有足够的声望发表评论,但希望添加到马克的答案。

您可以自己注册供应商。 它们基本上是带有$get方法的对象(或构造函数)。 当你注册一个提供者时,它的标准版本可以像服务或者工厂一样使用,但是提供者版本可以被使用。 所以注册为一个grumpy提供者

 angular.module('...', []) .provider('grumpy', GrumpyProviderObject) 

然后在configurationfunction中可用

  .config(['grumpyProvider', ..., function (grumpyProvider, ...) { ... }]) 

并可以简单地注入到控制器中

  .controller('myController', ['grumpy', ..., function (grumpy, ...) { ... }]) 

注入myControllergrumpy对象只是在myController上运行$get方法的GrumpyProviderObject 。 请注意,您注册的提供者也可以是常规的JavaScript构造函数。

注意:根据@Problematic的评论,提供者初始化(对angular.module().provider(…)的调用必须在configuration函数可用之前。

你可以这样做:

 (function() { 'use strict'; angular.module('name', name).config(config); // You can do this: config.$inject = ['$routeProvider', 'myService']; function config($routeProvider, myService) { // Or better to use this, but you need to use ng-annotate: /* ngInject */ } }); 

这是在这里描述的最佳实践

您可以手动调用angular.injector来访问应用程序的.config()块期间没有依赖关系的服务。 如果你创build的服务没有任何需要遍历的依赖,那么你可以使用这个:

 angular.module('myApp').config(function () { var myService = angular.injector(['ng']).get('myService'); }); 

这适用于其他简单的服务,如$http以及:

 angular.module('myApp').config(function () { var http = angular.injector(['ng']).get('$http'); }); 

注意:在configuration阶段,通常不需要注入服务,创build一个允许进行configuration的提供程序的devise会更好。 该文档说这个function暴露的情况下,第三方库需要访问已经运行的Angular应用程序的注入器。

如果你想注入依赖(假设从一个服务)来调用path(.config)中的函数forms,如下所示templateProvider.getTemplate('about')

 .state('index.about', {  url: "/about",  templateUrl: templateProvider.getTemplate('about'),  controller: 'AboutCtrl',  controllerAs: 'about',  data: {pageTitle: 'About Us Page'} }) 

您必须创build一个提供者。 不是服务或工厂。

以下是一个提供者的一个真实例子,它从名字中生成模板path:

 (function () {  'use strict';  angular    .module('mega-app')    .provider('template', provider);  function provider(CONSTANT) {    // The provider must include a $get() method This $get() method    // will be invoked using $injector.invoke() and can therefore use    // dependency-injection.    this.$get = function () {      return {}    };    /**     * generates template path from it's name     *     * @param name     * @returns {string}     */    this.getTemplate = function (name) {      return CONSTANT.TEMPLATES_URL + name + '/' + name + '.html';    }    /**     * generates component path from it's name     * @param name     * @returns {string}     */    this.getComponent = function (name) {      return CONSTANT.COMPONENTS_URL + name + '.html';    }  }; })(); 

这些提供程序在路由(.config)中的用法如下:

 (function () {  'use strict';  angular    .module('mega-app')    .config(routes);  function routes($stateProvider, $urlRouterProvider, templateProvider) {    $stateProvider   //----------------------------------------------------------------   // First State    //----------------------------------------------------------------      .state('index', {        abstract: true,        url: "/index",        templateUrl: templateProvider.getComponent('content'),        controller: 'IndexCtrl',        controllerAs: 'index',      })      //----------------------------------------------------------------      // State      //----------------------------------------------------------------      .state('index.home', {        url: "/home",        templateUrl: templateProvider.getTemplate('home'),        controller: 'HomeCtrl',        controllerAs: 'home',        data: {pageTitle: 'Home Page'}      })      //----------------------------------------------------------------      // State      //----------------------------------------------------------------      .state('index.about', {        url: "/about",        templateUrl: templateProvider.getTemplate('about'),        controller: 'AboutCtrl',        controllerAs: 'about',        data: {pageTitle: 'About Us Page'}      })    //----------------------------------------------------------------    // Default State    //----------------------------------------------------------------    $urlRouterProvider.otherwise('/index/home');  }; })(); 

VIP注意事项:

要注入提供程序,您必须将其与xxxProvider后缀(该提供程序的名称不应该后缀,仅在.config注入)。

如果它可以让你们中的一些人更容易。

根据这个答案中的解释 ,您可以将Provider附加到自定义服务,然后使用$get()访问内部函数。

这可能不是最干净的解决scheme,但是它能完成这项工作。

 module.config(function ($routeProvider, myServiceProvider) { // Call a function hello() on myService. myServiceProvider.$get().hello(); }); 
 angular.module('modulename').config(['$routeprovider','$controllerprovider',function($routeprovider,$controllerprovider){ angular.module('modulename').controllerProvider = $controllerProvider; angular.module('modulename').routeprovider=$routeprovider; $routeprovider.when('/',{ templateUrl: 'urlname', controller: 'controllername', resolve:{ 'variable':variablenamewithvalue } }).otherwise({ redirectTo: '/' }); }]); 

你可以试试这个:

 module.config(['$routeProvider', '$http', function ($routeProvider, $http) {}]);