【问题标题】:Error Unknown provider: $scopeProvider <- $scope when using $injector to inject $scope into controller使用 $injector 将 $scope 注入控制器时出现错误 Unknown provider: $scopeProvider <- $scope
【发布时间】:2016-05-26 09:24:28
【问题描述】:

以这种方式使用 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

这是一个plunker,其中有一个展示错误的示例,请检查 cmets 以查看替代方案,以查看只有范围而非自定义服务受此影响。
我发现了这个Angular bug,他们谈到在创建子 $scope 之前实例化控制器,Tomer Avni 回答了,所以:

  1. 为什么注入$scope 的第一种方法有效而第二种无效?
  2. 还有没有办法使用依赖注入的第二种方法 用$injector 注入$scope?

【问题讨论】:

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


    【解决方案1】:

    我已经在 gitter 上回复了你,但在这里回复也可以帮助其他有同样问题的人。


    当你给 Angular 一个函数调用时,它的值将从依赖注入中派生(例如服务、控制器等),Angular 将:

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

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

    $scope 在 DI 容器中不存在,只有 $rootScope 存在。因此,如果您直接访问注入器并请求 $scope 的实例,您将得到您在此处看到的注入错误。

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

    我希望这可以解释为什么您的示例不起作用。

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

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

    但是现在我们开始走上一条相当模糊的道路......直接注入$injector 是非常不典型的。如果可以的话,我会避免这种情况。您有必要这样做吗?

    【讨论】:

    • 我直接注入$injector,因为在我的应用程序中我有很多依赖项,所以函数参数变得很长,所以通过注入$injector我可以让它垂直,我猜我现在只注入$scope$injector
    • 好吧,我也遇到过类似的情况,虽然通常这表明你需要开始重构,但如果你无法绕过它,你可以随时将控制器参数放在新行:`function MyController ( someParam, anotherParam ) { } `
    • ..so 多行代码 sn-ps 在 cmets 中效果不佳 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 2013-10-19
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2016-05-09
    相关资源
    最近更新 更多