所有
让我对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有多少种依赖关系?
由于
答案 0 :(得分:4)
$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
是&#34;简单参数&#34;,它们是函数执行计算的值。想象一下,您想要向您的应用广播一条消息,表明已经执行了添加。在Angular中,我们可以使用$rootScope.$broadcast
方法。
function add(a, b) {
$rootScope.$broadcast('addition.done', a + b);
return a + b;
}
但是在这里,$rootScope
从未被宣布过。我们必须在我们的函数中加载$rootScope
服务。 Angular使用$injector.invoke
方法来执行此操作:它采用函数或数组(&#34;方括号&#34;表示法),从函数中提取服务名称 arguments / array elements,使用作为参数传递的相应服务调用该函数。
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
不是服务。事实上,他们不必是服务,因为他们是我们想要自己设定的价值观。对于注射器,它们是当地人。为了使用2
函数添加3
和add
,我们必须执行以下操作:
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
调用。