All:
让我对 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
方法将服务传递给函数,可以用给定的值替换请求的依赖项,有关详细信息,请参阅文档。我认识到在参数列表中混合服务和简单值是令人困惑的,因为我们无法知道哪个是服务,哪个是简单参数,但它以这种方式工作。
我们可以考虑在实例化新控制器时执行这样的事情:
var $rootScope = $injector.get('$rootScope');
$injector.invoke(controller, context /*the this binding*/, {
$scope: $rootScope.new()
});
有关更多详细信息,另请参阅控制器服务的代码。
更新:$scope
和服务之间的差异
取这个函数:
function add(a, b) {
return a + b;
}
a
和b
是"简单参数",它们是函数执行计算的值。假设你想要向应用广播一条消息,指出刚刚执行了添加。在 Angular 中,我们可以使用 $rootScope.$broadcast
方法。
function add(a, b) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
但在这里,$rootScope
从未被宣布过。我们必须在函数中加载$rootScope
服务。Angular 使用 $injector.invoke
方法来做到这一点:它接受一个函数或数组("方括号"表示法),从函数参数/数组元素中提取服务名称,并使用作为参数传递的相应服务调用函数。
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
不是服务。事实上,它们不一定是服务,因为它们是我们想要为自己设定的价值观。对于注射器,他们是当地人。为了使用 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
。如果scope
是一个服务,它会抛出错误,但实际上它不会,因为link
函数不是用$injector.invoke
调用的。