错误未知提供程序:$ scopeProvider< - $ scope使用$ injector将$ scope注入控制器时

时间:2016-02-15 12:51:10

标签: javascript angularjs dependency-injection scope angularjs-injector

以这种方式使用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已经回答了,所以:

  1. 为什么注入$scope的第一种方式工作而第二种方法不工作?
  2. 有没有办法使用第二种依赖注入方法 用$injector注入$scope

1 个答案:

答案 0 :(得分:1)

我已经回复了你的问题,但在这里回答以及它可能会帮助其他有同样问题的人。

当您为Angular提供一个函数来调用具有将从依赖注入派生的值(例如服务,控制器等)时,Angular将:

  • 在函数对象上查找.$inject属性,该属性应该是依赖项名称数组作为字符串(例如['$scope'])。
  • 如果未定义$inject,它将使用函数定义的参数(在大多数情况下都适用,除非您缩小代码并且名称被破坏)。

因此,简而言之,它将查找您在DI容器中指定的名称。

DI容器中不存在

$scope ,只有$rootScope。因此,如果您直接访问注射器并要求$scope的实例,您将会收到您在此处看到的注射错误。

在它工作的示例中,您不是直接访问注入器,而是依赖Angular来研究如何创建控制器。这是一个微妙的差异,但在这种情况下是一个重要的。在Angular中,在创建控制器实例时,它会将$scope解析为调用$rootScope.$new()的结果(即在单元测试中手动实例化控制器时将执行的操作)。

我希望这能解释为什么你的例子不起作用。

至于第二个问题,您可以通过执行以下操作手动获取范围实例:

var $scope = $injector.get('$rootScope').$new();

但现在我们开始走上一条非常阴暗的道路......直接注入$injector非常不典型。如果可以,我会避免这样做。你有什么理由需要这样做吗?