为什么我可以访问在隔离范围之外定义的属性?

时间:2014-07-12 14:41:45

标签: angularjs

我有以下HTML:

<ng-view>
    <tabset>
        <tab>
            <tab-heading>
                <i class="glyphicon glyphicon-info-sign"></i>
            </tab-heading>
            <div>
                <div>
                    <div>{{selectedWord.translation}}</div>
                </div>
    ...
</ng-view>

为视图加载的控制器:

angular.module('app').controller('SampleController', function ($scope) {
    $scope.selectedWord = {translation: '[te]'};
}

指令ng-view创建一个新的作用域,然后我将其作为参数注入SampleController构造函数中。

tabset创建自己的独立范围,因此它不会从ng-view创建的范围继承属性。

.directive('tabset', function() {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    scope: {
      type: '@'
    },

每个tab指令还创建自己的范围,该范围也不是从tabset指令创建的范围继承的。

.directive('tab', ['$parse', function($parse) {
  return {
    require: '^tabset',
    restrict: 'EA',
    replace: true,
    templateUrl: 'template/tabs/tab.html',
    transclude: true,
    scope: {
      active: '=?',
      heading: '@',
      onSelect: '&select', //This callback is called in contentHeadingTransclude
                          //once it inserts the tab's content into the dom
      onDeselect: '&deselect'
    },

我不明白为什么可以从selectedWord.translation指令创建的范围内访问ng-view指令创建的范围中定义的属性tab。它是隔离范围本身,前面是tabset)创建的隔离范围?

1 个答案:

答案 0 :(得分:2)

当指令使用transclusion时,它会为已转换的内容(有时也称为transclusion scope)创建子范围。当指令还定义了隔离范围时,实际上在同一指令中使用了两个范围:

  
      
  1. 转换范围 - 绑定到已转录的内容
  2.   
  3. 隔离范围 - 绑定到您的模板(如果已定义)或作为指令的私有范围提供。
  4.   

因此selectedWord可解析的原因是因为被转换的内容被绑定到ngView的转换范围。并且任何指令的转换范围只是一个子范围,它原型地从其父级继承范围。

任何使用包含的指令都是如此:

示例

<!-- name defined in parent scope -->
<div ng-init="name='test'">
    <!-- ng-if creates a child scope for its transcluded contents
       The child scope prototypically inherits scope from its parents -->
    <div ng-if="true">
        <!-- this is the transcluded contents for ng-if -->
        <div> 
            <my-dir-using-isolate-scope>
               <!-- this is the transcluded contents for 
                    my-dir-using-isolate-scope directive --> 
               {{ name }} 
            </my-dir-using-isolate-scope>
        </div>
    </div>
</div>