如何以角度将依赖项注入module.config(configFn)


74

-在角度,我们可以注入$routeProviderconfig功能

module.config(function ($routeProvider) {


});

我想将我的服务注入其中

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


});

我确定服务定义正确,unknown myService但当我注入

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


});

它仍然说unknown $http

你知道为什么吗?


您只能注入$http配置文件,例如$httpProviderdocs.angularjs.org/api/ng/provider/$httpProvider
露水

Answers:


95

在“模块”页面的“模块加载和依赖项”部分:

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

运行块-创建注射器后执行,并用于启动应用程序。只能将实例和常量注入运行块中。这是为了防止在应用程序运行期间进行进一步的系统配置。

因此,您不能将自己的服务或$ http之类的内置服务注入config()。使用run()代替。


感谢您的回答,但是为什么可以将$ routeProvider注入到config函数中,这是唯一可以注入到config函数中的依赖项吗?我对此表示怀疑。
Fred Yang

2
如前所述,可以将任何“提供程序”(内置的Angular或您自己的)或“常数”注入config()函数。这里是一个包含内置提供一些角度源代码:github.com/angular/angular.js/blob/...
马克Rajcok

57

我没有足够的声誉来发表评论,但我想补充一下Mark的答案。

您可以自己注册提供商。它们基本上是带有$get方法的对象(或构造函数)。注册提供程序时,可以像服务或工厂一样使用其标准版本,但是可以更早使用提供程序版本。因此grumpy,注册为

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

然后可以在配置功能中使用

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

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

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

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

注意:根据@Problematic的注释,提供程序初始化(对的调用angular.module().provider(…)必须在config函数可用之前进行。


4
谢谢你 值得注意的是,配置函数必须在提供程序之后才能注入。可能很明显,但它使我绊倒了!
2013年

1
这次真是万分感谢。现在,我看到提供程序本身必须没有后缀'Provider'。我的配置正在寻找找不到的ProviderProvider。
Etienne Marais 2013年

2
这也适用于constants,因为常量也是提供者。
Patrick Hillert

10

您可以这样做:

(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 */

    }
});

这里介绍的最佳做法


为什么?我最近做的。
Lyubimov Roman

1
@DanielKobe .config('config',config); 应该是.config(config);
m1kael 2015年

是的,我的错误,我已经编辑了答案。我对简单配置的服务感到困惑。不会像服务那样​​注入配置。
Lyubimov Roman

尚未尝试过,但这不起作用。这只是尝试在config-section中注入服务的另一种方法。如果可行,这是Angular中的错误。
hgoebl 2015年

3
这不应该起作用,我很好奇为什么要这么多投票?看到这里Configuration blocks: get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
Saorikido

5

您可以手动调用angular.injector以访问在应用程序阻止期间没有依赖性的服务.config()。如果您创建的服务没有任何需要遍历的依赖项,那么您可以使用以下方法:

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

注意:通常,您不需要在配置阶段插入服务,最好设计一个允许配置的提供程序。文档说,此功能在第三方库需要访问已经运行的Angular应用的注入器的情况下公开。


我用$ location尝试了这个,但是那个不起作用。给出“未知提供程序:$ rootElementProvider”错误信息。
AndrewR

2
当您调用$injector.get('serviceName')尚未实例化的服务时(如在该.config()块中),注入器将尝试在该实例上实例化该服务。如果该服务具有任何依赖关系,则会因缺少这些部门而引发错误。不幸的是,调用时无法提供依赖项.get()$location 依赖$rootElement,因此无法以这种方式加载。
亚历克斯·罗斯

4

如果要注入依赖项(比如说从服务中获取)以在路由(.config)中调用函数形式,如下所示templateProvider.getTemplate('about')

.state('index.about', {  

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

})  

您必须创建一个提供程序。不是服务,也不是工厂。

这是Provider的真实示例,该Provider从名称生成模板路径:

(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中注入时)。


我想在配置中进行$ http调用,并获取一些包含网站语言的json文件,然后将其传递给语言配置...。每个人都在谈论$ get,但$ get似乎并没有自己运行,您是否可以提供更多信息,所以如果此提供程序应替换配置文件,则可以,并且如果它稍后可以调用$ http等,您可以这样做吗?
deadManN

-2

如果它可以使某些人的事情变得容易。

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

它可能不是最干净的解决方案,但可以完成工作。

module.config(function ($routeProvider, myServiceProvider) {
 // Call a function hello() on myService.
 myServiceProvider.$get().hello();
});

未被捕获的TypeError:$ locationProvider。$ get不是函数(…)
加里

嗨,您应该可以使用 $locationProvider原样。它已经是提供商。无需使用$get()hack。我想念什么吗?
安德鲁

它没有.path或任何东西,只有。$ get作为Array [6],hashPrefix函数和html5Mode函数。我正在像$ routeProvider那样将$ locationProvider注入到配置中。
加里

-15

您可以尝试以下方法:

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

配置块中仅允许提供程序和常量进行注入。直到执行配置块,服务才准备就绪。
史蒂文·罗杰斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.