AngularJS指令控制器's的作用域可以从外部指令访问,为什么?

AngularJS directive controller's scope accessible from outside directive, why?

本文关键字:指令 从外部 访问 为什么 作用域 指令控制器 AngularJS      更新时间:2023-09-26

在实验中发现了一些有趣的东西。由于某种原因,我能够从指令外部访问指令声明中指定的控制器的作用域。

下面是示例代码:
myApp.directive('lockToggle', function () {
    return {
        restrict: 'A',
        link: function (scope, elem) {
            elem.bind('click', function (e) {
                scope.locked = !scope.locked;
                scope.$apply();
            });
        },
        controller: function ($scope) {
            $scope.locked = false;
            $scope.hello = function () {
                alert('hello');
            };
        }
    };
});

,这里是我的标记:

<button lock-toggle>
  Toggle Lock
</button>
<button ng-disabled="locked" ng-click="hello()">
  Click Me!
</button>

当我点击按钮Toggle Lock, Click Me!按钮禁用和启用正确。并且,当我点击Click Me!按钮时,控制器范围上的hello()方法被调用。

我的问题是为什么?在指令中声明的控制器的作用域不应该与html中的指令作用域隔离吗?我希望它的行为方式与其他控制器相同,例如:
<!--Can't access the scope of MyController-->
<div ng-controller="MyController">
  .    
  .
  <!--CAN access the scope of MyController-->
  .
  .
</div>
<!--Can't access the scope of MyController-->

但是由于某种原因,这似乎不适用于我前面的例子。为什么会这样?

你可以决定你的指令作用域应该如何表现,以及它是否应该继承父作用域:

myApp.directive('lockToggle', function () {
return {
    restrict: 'A',
    scope: {}, // Will create an isolated scope
    link: function (scope, elem) {
        elem.bind('click', function (e) {
            scope.locked = !scope.locked;
            scope.$apply();
        });
    },
    controller: function ($scope) {
        $scope.locked = false;
        $scope.hello = function () {
            alert('hello');
        };
    }
  };
});

目前,您没有指定scope属性,它等于scope:false。因此,该指令不创建作用域。

更多信息

  • 关于指令
  • 的一个非常简洁的讲座
  • 角文档

可以访问的原因是您将它添加到父控制器共享的相同作用域:

controller: function ($scope) {
    $scope.locked = false;
    $scope.hello = function () {
        alert('hello');
    };
}

这里$scope是你的父控制器,因为在JavaScript对象是通过引用,所以你添加它到你的父控制器。

如果你只想为指令作用域初始化变量,那么使用scope:

scope:{
  //properties
}