如何在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, ...) { ... }])
注入myController
的grumpy
对象只是在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) {}]);