AngularJS 控制器定义中是否存在 $scope 依赖注入?
Is $scope dependecy injection in AngularJS controller definition?
全部:
AngularJS 中的依赖注入让我感到困惑的是它的概念(我想我还没有完全理解 DI):
我想知道如何判断应该(并且可以)注入哪些依赖项?
例如:
如果我定义一个控制器和指令:
app.controller("maincontroller", ["$scope", "dependency1", function($scope, dependency1){
}])
app.directive("dir1", ["dependency2", "dependency3",
function(dependency2, dependency3){
return {
restrict: "AE",
scope:{},
controller: function($scope){},
link:function(scope, EL, attrs, ctrl){}
};
}])
我想知道为什么我需要在控制器中注入 $scope 作为依赖项,但不需要在指令定义中这样做。更重要的是:如果我将 $scope 放在该指令函数中,它会给我一个错误:
Error: error:unpr
Unknown Provider
Unknown provider: $scopeProvider <- $scope <- dir1Directive
[1] 这个 $scope 是依赖还是 [2] 我对依赖的理解是完全错误的(有人告诉我$scope 不是依赖)或者 [3] 我对指令 def 函数的理解是错误的(只有服务可以放在指令 def 函数中)?
如果我错的是最后一个,那么AngularJS有多少种依赖关系?
谢谢
$scope
实际上不是服务!
这就是为什么您不必将其作为指令的依赖项传递的原因。 $scope
是一个局部传递给注入器,一个传递给函数的值,就好像我会做 console.log(myValue)
一样。 myValue
不是服务。
$injector
的 invoke
方法将服务传递给函数,可以用给定值替换请求的依赖项,有关详细信息,请参阅 the docs。我认识到在参数列表中混合服务和简单值会造成混淆,因为我们无法知道哪个是服务,哪个是简单参数,但它是这样工作的。
我们可以认为在实例化新控制器时会执行类似这样的操作:
var $rootScope = $injector.get('$rootScope');
$injector.invoke(controller, context /*the this binding*/, {
$scope: $rootScope.new()
});
另请参阅 the code of the controller service 了解更多详细信息。
更新:$scope
和服务
之间的差异
使用这个函数:
function add(a, b) {
return a + b;
}
a
和b
是"simple arguments",它们是函数执行计算的值。想象一下,您想要向您的应用程序广播一条消息,说明刚刚执行了添加操作。在Angular中,我们可以使用$rootScope.$broadcast
方法。
function add(a, b) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
但在这里,$rootScope
从未被声明过。我们必须在我们的函数中加载 $rootScope
服务。 Angular 使用 $injector.invoke
方法来做到这一点:它接受一个函数或数组("square bracket" 符号),从函数中提取服务名称 arguments/array 个元素,并且 使用相应的服务调用函数 作为参数传递。
function add(a, b, $rootScope) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
var $injector = angular.injector(['ng']); // Creates the injector, with the services of `ng` module.
$injector.invoke(add); // Calls the function with the requested services
它会抛出错误,因为 a
和 b
不是服务。事实上,它们不一定是服务,因为它们是我们要为自己设定的价值观。对于注入器,它们是 locals。为了使用 add
函数执行 2
和 3
的加法,我们必须执行以下操作:
function add(a, b, $rootScope) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
var $injector = angular.injector(['ng']);
$injector.invoke(add, this, {
a: 2, // When requesting the `a` service, return the value `2`
b: 3 // The same here, with `b` and `3`
});
控制器也是如此。 $scope
本身不是一个服务,而是一个新的作用域,每次加载指令时都会构建。与 a
和 b
一样,新创建的 $scope
是 函数执行某些逻辑和修改的值 。 $scope
不是依赖项,而是函数的参数。 而且因为 $injector
从参数列表中提取依赖项,所以我们无法判断是否争论是否是一项服务(除非您已经知道,但这不是证据)。此处,$scope
不是服务 ,并且与指令中的 link
函数中的对象相同。请注意,文档并未将范围参数命名为 $scope
,而是命名为 scope
。如果 scope
是一个服务,它会抛出一个错误,但实际上它不会,因为 link
函数不是用 $injector.invoke
.
调用的
全部:
AngularJS 中的依赖注入让我感到困惑的是它的概念(我想我还没有完全理解 DI):
我想知道如何判断应该(并且可以)注入哪些依赖项?
例如:
如果我定义一个控制器和指令:
app.controller("maincontroller", ["$scope", "dependency1", function($scope, dependency1){
}])
app.directive("dir1", ["dependency2", "dependency3",
function(dependency2, dependency3){
return {
restrict: "AE",
scope:{},
controller: function($scope){},
link:function(scope, EL, attrs, ctrl){}
};
}])
我想知道为什么我需要在控制器中注入 $scope 作为依赖项,但不需要在指令定义中这样做。更重要的是:如果我将 $scope 放在该指令函数中,它会给我一个错误:
Error: error:unpr
Unknown Provider
Unknown provider: $scopeProvider <- $scope <- dir1Directive
[1] 这个 $scope 是依赖还是 [2] 我对依赖的理解是完全错误的(有人告诉我$scope 不是依赖)或者 [3] 我对指令 def 函数的理解是错误的(只有服务可以放在指令 def 函数中)?
如果我错的是最后一个,那么AngularJS有多少种依赖关系?
谢谢
$scope
实际上不是服务!
这就是为什么您不必将其作为指令的依赖项传递的原因。 $scope
是一个局部传递给注入器,一个传递给函数的值,就好像我会做 console.log(myValue)
一样。 myValue
不是服务。
$injector
的 invoke
方法将服务传递给函数,可以用给定值替换请求的依赖项,有关详细信息,请参阅 the docs。我认识到在参数列表中混合服务和简单值会造成混淆,因为我们无法知道哪个是服务,哪个是简单参数,但它是这样工作的。
我们可以认为在实例化新控制器时会执行类似这样的操作:
var $rootScope = $injector.get('$rootScope');
$injector.invoke(controller, context /*the this binding*/, {
$scope: $rootScope.new()
});
另请参阅 the code of the controller service 了解更多详细信息。
更新:$scope
和服务
之间的差异
使用这个函数:
function add(a, b) {
return a + b;
}
a
和b
是"simple arguments",它们是函数执行计算的值。想象一下,您想要向您的应用程序广播一条消息,说明刚刚执行了添加操作。在Angular中,我们可以使用$rootScope.$broadcast
方法。
function add(a, b) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
但在这里,$rootScope
从未被声明过。我们必须在我们的函数中加载 $rootScope
服务。 Angular 使用 $injector.invoke
方法来做到这一点:它接受一个函数或数组("square bracket" 符号),从函数中提取服务名称 arguments/array 个元素,并且 使用相应的服务调用函数 作为参数传递。
function add(a, b, $rootScope) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
var $injector = angular.injector(['ng']); // Creates the injector, with the services of `ng` module.
$injector.invoke(add); // Calls the function with the requested services
它会抛出错误,因为 a
和 b
不是服务。事实上,它们不一定是服务,因为它们是我们要为自己设定的价值观。对于注入器,它们是 locals。为了使用 add
函数执行 2
和 3
的加法,我们必须执行以下操作:
function add(a, b, $rootScope) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
var $injector = angular.injector(['ng']);
$injector.invoke(add, this, {
a: 2, // When requesting the `a` service, return the value `2`
b: 3 // The same here, with `b` and `3`
});
控制器也是如此。 $scope
本身不是一个服务,而是一个新的作用域,每次加载指令时都会构建。与 a
和 b
一样,新创建的 $scope
是 函数执行某些逻辑和修改的值 。 $scope
不是依赖项,而是函数的参数。 而且因为 $injector
从参数列表中提取依赖项,所以我们无法判断是否争论是否是一项服务(除非您已经知道,但这不是证据)。此处,$scope
不是服务 ,并且与指令中的 link
函数中的对象相同。请注意,文档并未将范围参数命名为 $scope
,而是命名为 scope
。如果 scope
是一个服务,它会抛出一个错误,但实际上它不会,因为 link
函数不是用 $injector.invoke
.