【问题标题】:how to inject dependency into module.config(configFn) in angular如何以角度将依赖项注入module.config(configFn)
【发布时间】:2013-02-23 13:26:47
【问题描述】:

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

module.config(function ($routeProvider) {


});

我想将我的服务注入其中

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


});

我确定服务定义正确,但它会抛出一个异常,说unknown myService,当我注入时发生事件

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


});

它仍然显示unknown $http

你知道为什么吗?

【问题讨论】:

标签: angularjs


【解决方案1】:

来自Modules 页面,“模块加载和依赖项”部分:

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

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

因此您不能将自己的服务或 $http 等内置服务注入到 config() 中。请改用run()

【讨论】:

  • 感谢您的回答,但是为什么 $routeProvider 可以注入到配置函数中,这是唯一可以注入到配置函数中的依赖项吗?我对此表示怀疑。
  • 如上所述,任何“提供者”(Angular 内置的或您自己的)或“常量”都可以注入到 config() 函数中。这是一些包含内置提供程序的 Angular 源代码:github.com/angular/angular.js/blob/…
【解决方案2】:

我没有足够的声誉来发表评论,但想添加到马克的回答中。

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

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

然后在配置函数中可用

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

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

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

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

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

【讨论】:

  • 谢谢。值得注意的是,配置函数必须在提供者之后才能注入。可能很明显,但它绊倒了我!
  • 谢谢你。我现在看到提供者本身必须没有后缀“提供者”。我的配置正在寻找它找不到的 ProviderProvider。
  • 这也适用于constants,因为常量也是提供者。
【解决方案3】:

你可以这样做:

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

    }
});

这是here 描述的最佳实践

【讨论】:

  • 为什么?我最近做了。
  • @DanielKobe .config('config', config);应该是 .config(config);
  • 是的,我的错误,我已经编辑了答案。我对简单配置的服务感到困惑。配置不像服务那样​​注入。
  • 没试过,但这应该行不通。这只是尝试在配置部分中注入服务的另一种方式。如果它有效,那就是 Angular 中的一个错误。
  • 这应该行不通,我很好奇为什么这么多赞成?看这里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.
【解决方案4】:

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

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

注意:通常您不需要在配置阶段注入服务,最好创建一个允许配置的提供程序。文档说,当第 3 方库需要访问已经运行的 Angular 应用程序的注入器时,就会公开此功能。

【讨论】:

  • 我用 $location 试过这个,但那个不起作用。给出“未知提供者:$rootElementProvider”错误消息。
  • 当您在尚未实例化的服务上调用$injector.get('serviceName') 时(如在.config() 块中),注入器会尝试在现场实例化该服务。如果该服务有任何依赖项,它会抛出一个错误,因为这些依赖项丢失了。不幸的是,当您调用.get() 时,您无法提供依赖项。 $locationhas a dependency$rootElement上,所以不能这样加载。
【解决方案5】:

如果您想注入依赖项(比如说从服务中)以调用路由(.config)中的函数表单,如下所示templateProvider.getTemplate('about')

.state('index.about', {  

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

})  

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

这是一个真实的 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';  
        }  

    };  
})();  

此类Provider在路由(.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');  
    };  
})();  

贵宾注意:

要注入提供程序,您必须使用 xxxProvider 对其进行后缀(提供程序的名称不应后缀,仅在 .config 中注入时)。

【讨论】:

  • 我想在我的配置中做 $http 调用,并获取一些包含网站语言的 json 文件,然后将它们传递给语言配置....每个人都在谈论 $get 但 $get似乎无法自行运行,您能否提供更多信息,所以如果此提供程序应该替换配置文件,它会这样做,并且如果它以后有某种方式调用 $http 等,请改为这样做?
【解决方案6】:

如果它能让你们中的一些人更轻松。

根据explained in this answer,您只需将Provider 附加到您的自定义服务,然后使用$get() 访问内部函数。

它可能不是最干净的解决方案,但它确实有效。

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

【讨论】:

  • Uncaught TypeError: $locationProvider.$get is not a function(...)
  • 嗨,您应该可以照原样使用$locationProvider。它已经是提供者了。无需使用$get() hack。我错过了什么吗?
  • 它没有 .path 或任何东西,只有 .$get 作为 Array[6]、hashPrefix 函数和 html5Mode 函数。我正在 $injecting '$locationProvider' 到 $routeProvider 之类的配置中。
【解决方案7】:

你可以试试这个:

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

【讨论】:

  • 在配置块中只允许提供者和常量用于注入。直到配置块被执行之后,服务才准备好。
猜你喜欢
  • 1970-01-01
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2020-12-20
相关资源
最近更新 更多