以这种方式使用DI时:
var MainController = function MainController($scope) {
//use $scope here
};
MainController.$inject = ["$scope"];
它起作用,但是当它像这样使用时:
var MainController = function MainController($injector) {
var $scope = $injector.get("$scope");
};
MainController.$inject = ["$injector"];
这将导致错误:
错误:[$ injector:unpr]未知提供者:$ scopeProvider< - $ scope
这是一个plunker,其中有一个示例显示错误,请检查备注的注释,以查看只有范围而非自定义服务受此影响。
我找到了这个Angular bug,他们谈到在创建子$ scope之前实例化的控制器,Tomer Avni已经回答了,所以:
$scope
的第一种方式工作而第二种方法不工作? $injector
注入$scope
?答案 0 :(得分:1)
我已经回复了你的问题,但在这里回答以及它可能会帮助其他有同样问题的人。
当您为Angular提供一个函数来调用具有将从依赖注入派生的值(例如服务,控制器等)时,Angular将:
.$inject
属性,该属性应该是依赖项名称数组作为字符串(例如['$scope']
)。$inject
,它将使用函数定义的参数(在大多数情况下都适用,除非您缩小代码并且名称被破坏)。因此,简而言之,它将查找您在DI容器中指定的名称。
DI容器中不存在 $scope
,只有$rootScope
。因此,如果您直接访问注射器并要求$scope
的实例,您将会收到您在此处看到的注射错误。
在它工作的示例中,您不是直接访问注入器,而是依赖Angular来研究如何创建控制器。这是一个微妙的差异,但在这种情况下是一个重要的。在Angular中,在创建控制器实例时,它会将$scope
解析为调用$rootScope.$new()
的结果(即在单元测试中手动实例化控制器时将执行的操作)。
我希望这能解释为什么你的例子不起作用。
至于第二个问题,您可以通过执行以下操作手动获取范围实例:
var $scope = $injector.get('$rootScope').$new();
但现在我们开始走上一条非常阴暗的道路......直接注入$injector
非常不典型。如果可以,我会避免这样做。你有什么理由需要这样做吗?