是 AngularJS 控制器定义中的$scope依赖注入



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

$injectorinvoke方法将服务传递给函数,可以用给定的值替换请求的依赖项,有关详细信息,请参阅文档。我认识到在参数列表中混合服务和简单值是令人困惑的,因为我们无法知道哪个是服务,哪个是简单参数,但它以这种方式工作。

我们可以考虑在实例化新控制器时执行这样的事情:

var $rootScope = $injector.get('$rootScope');
$injector.invoke(controller, context /*the this binding*/, {
    $scope: $rootScope.new()
});

有关更多详细信息,另请参阅控制器服务的代码。

更新:$scope和服务之间的差异

取这个函数:

function add(a, b) {
    return a + b;
}

ab是"简单参数",它们是函数执行计算的值。假设你想要向应用广播一条消息,指出刚刚执行了添加。在 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

它将引发错误,因为ab不是服务。事实上,它们不一定是服务,因为它们是我们想要为自己设定的价值观。对于注射器,他们是当地人。为了使用 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 。如果scope是一个服务,它会抛出错误,但实际上它不会,因为link函数不是用$injector.invoke调用的。

最新更新