2014-05-23 47 views
3

在實驗過程中遇到了一些有趣的事情。出於某種原因,我可以從指令外部訪問指令聲明中指定的控制器的作用域。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--> 

但由於某些原因,這似乎並不適用於我前面的例子以上。爲什麼是這樣?

回答

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。因此,該指令不會創建範圍。

更多信息

+0

啊確定,所以,在我上面的例子,是我的父母範圍'$ rootScope'?或者,如何從父範圍繼承允許我訪問該繼承範圍之外的新增屬性?我期望繼承過程產生一個父範圍的副本,與原型鏈接,而不是修改父範圍本身(這似乎是上述情況),而不是副本。 – pje

+0

在您的示例中,指令範圍等於處理該標記部分其餘部分的範圍。它不是$ rootScope,而是它的一個孩子。如果您想向指令範圍添加不直接對父級可見的屬性,請創建一個獨立的範圍('scope:{}')或告訴指令創建一個新的子範圍:'scope:true'。 – Sprottenwels

+0

我想補充一點,我對這個話題也很困惑。我提供的第一個鏈接幫助我最終理解了這個概念:) – Sprottenwels

1

的原因,它是可訪問的是你將它添加到你的父控制器共享相同的範圍:

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

這裏的$ scope是你的父控制器,因爲在JavaScript中,對象是通過引用的方式,因此你可以將它添加到你的父控制器中。

如果要初始化變量僅適用範圍的指令,然後使用範圍:

scope:{ 
    //properties 
}