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 不是服务。

$injectorinvoke 方法将服务传递给函数,可以用给定值替换请求的依赖项,有关详细信息,请参阅 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;
}

ab是"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

它会抛出错误,因为 ab 不是服务。事实上,它们不一定是服务,因为它们是我们要为自己设定的价值观。对于注入器,它们是 locals。为了使用 add 函数执行 23 的加法,我们必须执行以下操作:

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 本身不是一个服务,而是一个新的作用域,每次加载指令时都会构建。与 ab 一样,新创建的 $scope 函数执行某些逻辑和修改的值 $scope 不是依赖项,而是函数的参数。 而且因为 $injector 从参数列表中提取依赖项,所以我们无法判断是否争论是否是一项服务(除非您已经知道,但这不是证据)。此处,$scope 不是服务 ,并且与指令中的 link 函数中的对象相同。请注意,文档并未将范围参数命名为 $scope,而是命名为 scope。如果 scope 是一个服务,它会抛出一个错误,但实际上它不会,因为 link 函数不是用 $injector.invoke.

调用的