AngularJS指令控制器范围可从外部指令访问,为什么?

时间:2014-05-23 05:59:12

标签: javascript angularjs

在尝试时遇到了一些有趣的事情。出于某种原因,我能够从指令外部访问指令声明中指定的控制器的范围。

以下是示例代码:

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-->

但出于某种原因,这似乎并不适用于我之前的上述例子。为什么是这样?

2 个答案:

答案 0 :(得分:3)

您可以决定指令范围的行为方式以及它是否应从父作用域继承:

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。因此,该指令不会创建范围。

更多信息

答案 1 :(得分:1)

可访问的原因是您将其添加到父控制器共享的相同范围:

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

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

如果只想为指令范围初始化变量,请使用范围:

scope:{
  //properties
}