错误未知提供者:$scopeProvider <- $scope 使用 $injector 将 $scope 注入控制器时
Error Unknown provider: $scopeProvider <- $scope when using $injector to inject $scope into controller
以这种方式使用 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"];
这将导致错误:
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
这里有一个 plunker 示例,其中包含一个展示错误的示例,请查看注释以了解替代方案,以了解只有范围而非自定义服务受此影响。
我发现这个 Angular bug where they talk about the controller being instantiated before the child $scope is being created as Tomer Avni 已回答,所以:
- 为什么第一种注入方式
$scope
有效而第二种注入方式无效?
- 还有没有办法使用依赖注入的第二种方法
用
$injector
注入 $scope
?
我已经在 gitter 上回复了你,但在这里回答以及它可能会帮助其他有同样问题的人。
当您给 Angular 一个函数调用时,该函数的值将从依赖注入(例如服务、控制器等)派生,Angular 将:
- 在函数对象上寻找
.$inject
属性,它应该是依赖名称作为字符串的数组(例如 ['$scope']
)。
- 如果
$inject
未定义,它将使用函数定义的参数(这在大多数情况下有效,除非您缩小代码并且名称被破坏)。
因此,简而言之,它将查找您在 DI 容器中指定的名称。
$scope
在 DI 容器中不存在 ,只有 $rootScope
存在。因此,如果您直接访问注入器并请求 $scope
的实例,您将得到您在此处看到的注入错误。
在它起作用的示例中,您没有直接访问注入器,而是依赖于 Angular 计算如何创建您的控制器。这是一个细微的差别,但在这种情况下是一个重要的差别。在 Angular 中,当创建控制器实例时,它会将 $scope
解析为调用 $rootScope.$new()
的结果(即在单元测试中手动实例化控制器时您将执行的操作)。
我希望这能解释为什么您的示例不起作用。
关于第二个问题,您可以通过执行以下操作手动获取作用域实例:
var $scope = $injector.get('$rootScope').$new();
但现在我们开始走上一条相当阴暗的道路......直接注入 $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"];
这将导致错误:
Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
这里有一个 plunker 示例,其中包含一个展示错误的示例,请查看注释以了解替代方案,以了解只有范围而非自定义服务受此影响。
我发现这个 Angular bug where they talk about the controller being instantiated before the child $scope is being created as Tomer Avni 已回答,所以:
- 为什么第一种注入方式
$scope
有效而第二种注入方式无效? - 还有没有办法使用依赖注入的第二种方法
用
$injector
注入$scope
?
我已经在 gitter 上回复了你,但在这里回答以及它可能会帮助其他有同样问题的人。
当您给 Angular 一个函数调用时,该函数的值将从依赖注入(例如服务、控制器等)派生,Angular 将:
- 在函数对象上寻找
.$inject
属性,它应该是依赖名称作为字符串的数组(例如['$scope']
)。 - 如果
$inject
未定义,它将使用函数定义的参数(这在大多数情况下有效,除非您缩小代码并且名称被破坏)。
因此,简而言之,它将查找您在 DI 容器中指定的名称。
$scope
在 DI 容器中不存在 ,只有 $rootScope
存在。因此,如果您直接访问注入器并请求 $scope
的实例,您将得到您在此处看到的注入错误。
在它起作用的示例中,您没有直接访问注入器,而是依赖于 Angular 计算如何创建您的控制器。这是一个细微的差别,但在这种情况下是一个重要的差别。在 Angular 中,当创建控制器实例时,它会将 $scope
解析为调用 $rootScope.$new()
的结果(即在单元测试中手动实例化控制器时您将执行的操作)。
我希望这能解释为什么您的示例不起作用。
关于第二个问题,您可以通过执行以下操作手动获取作用域实例:
var $scope = $injector.get('$rootScope').$new();
但现在我们开始走上一条相当阴暗的道路......直接注入 $injector
是非常不典型的。如果可以的话,我会避免这种情况。您是否需要这样做?