我想知道你何时会使用$injector.get('someService')
vs直接注入该服务。
基本上,下面两个代码的区别是什么?
angular
.module('myApp')
.controller('MyController', MyController);
/** Difference of this **/
MyController.$inject = ['$rootScope', '$route']; // and more services
MyController($rootScope, $route)
{
/* ... */
}
/** And this **/
MyController.$inject = ['$injector'];
MyController($injector)
{
var $rootScope = $injector.get('$rootScope');
var $route = $injector.get('$route');
/* and so on */
}
如果你不确定你的控制器需要什么,或者你将来会更新它,并且你重构了它,那么使用$injector
它会更容易添加/删除依赖项。
答案 0 :(得分:6)
第一种方法使用依赖注入,而第二种方法使用服务定位器模式。依赖注入具有以下优点:
它使组件的依赖关系显式化。例如,您可以查看控制器的构造函数,并立即知道它需要哪些依赖项。使用服务定位器,您通常不知道,因为控制器可能随时调用服务定位器。
它使单元测试更容易。例如,您可以使用$controller
服务来实例化控制器,并通过locals
参数向模拟对象提供它。这比定义一堆AngularJS服务或工厂更容易,以便$injector
可以解决它们。与#1结合使用会变得更糟:您可能不知道组件需要的所有依赖项,以便提供所有必要的模拟。
服务定位器确实提供了一些灵活性。例如,您的代码可能仅在存在时使用服务,如下所示:
if ($injector.has('serviceA')) $injector.get('serviceA').doSomething()
else someSomethingElse()
使用依赖项注入,如果在构建组件时serviceA
不存在,则会出现错误。
至于重构的简易性,我认为在构造函数中添加/删除参数很困难。正如您对问题的评论所指出的那样,像ngAnnotate
这样的工具将有助于使声明DRYer。
因此,我会坚持依赖注入,只在绝对必要时使用服务定位器。