在 AngularJS 中,如果子指令无法访问它的直接父级范围,那么它会继承其最近的非隔离祖先的范围吗?

In AngularJS, if the child directive cannot access it's immediate parent's scope then would it inherit its nearest, non-isolated ancestor's scope?

我有两个例子支持上述说法 -

1) 当使用 $scope (http://plnkr.co/edit/kFM77mVReS7AUwZsNzCV?p=preview) -

<!DOCTYPE html>
<html>

  <head>
    <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
    <script>
      angular
          .module('myApp', [])
          .directive('directive1', function() {
            return {
              controller: ['$scope', function($scope) {
                $scope.name = 'Directive1';
              }]
            };
          })
          .directive('directive2', function() {
            return {
              controller: ['$scope', function($scope) {
                $scope.name = 'Directive2';
              }],
              scope: {}
            };
          })
          .directive('directive3', function() {
            return {
              template: 'I am {{name}}'
            };
          });
    </script>
  </head>

  <body ng-app='myApp'>
    <directive1>
      <directive2>
        <directive3>
        </directive3>
      </directive2>
    </directive1>
  </body>

</html>

2) 当使用controllerAs(http://plnkr.co/edit/zmIRa1t87ZIMDS6X5rNo?p=preview)-

 <!DOCTYPE html>
<html>

  <head>
    <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
    <script>
      angular
          .module('myApp', [])
          .directive('directive1', function() {
            return {
              controller: function() {this.name = 'Directive1';},
              controllerAs: 'ctrl1'
            };
          })
          .directive('directive2', function() {
            return {
              controller: function() {this.name = 'Directive2';},
              controllerAs: 'ctrl2',
              transclude: true,
              template: '<ng-transclude></ng-transclude>',
              scope: {}
            };
          })
          .directive('directive3', function() {
            return {
              template: 'I am {{ctrl1.name}}'
            };
          });
    </script>
  </head>

  <body ng-app='myApp'>
    <directive1>
      <directive2>
        <directive3>
        </directive3>
      </directive2>
    </directive1>
  </body>

</html>

两个代码的输出都是 - I am Directive1 这表明 directive3 继承了 directive1 的范围(它不会访问 directive2 的范围,因为它有一个独立的范围)这证明我错误地假设一个独立的范围会破坏其父级之间的继承链指令及其子指令,因此其子指令的 none 将能够访问其任何祖先指令的范围。

我是不是遗漏了什么,或者我的作用域继承概念完全错误?

在所有 3 个指令中使用 scope:true,它将能够访问父级的所有范围

Note: scope:true will inherit the properties from the parent, but scope:{} will not inherit the properties from the parent.

<!DOCTYPE html>
<html>

<head>
  <script src="//code.angularjs.org/snapshot/angular.min.js"></script>
  <script>
    angular
      .module('myApp', [])
      .directive('directive1', function() {
        return {
          controller: ['$scope', function($scope) {
            $scope.name = 'Directive1';
          }],
          scope: true
        };
      })
      .directive('directive2', function() {
        return {
          controller: ['$scope', function($scope) {
            $scope.name = 'Directive2';
          }],
          scope: true
        };
      })
      .directive('directive3', function() {
        return {
          template: 'I am {{name}}',
          scope: true
        };
      });
  </script>
</head>

<body ng-app='myApp'>
  <directive1>
    <directive2>
      <directive3></directive3>
    </directive2>
  </directive1>
  
  <br>
  
  <directive1>
    <directive3></directive3>
  </directive1>

  <br>

  <directive2>
    <directive3></directive3>
  </directive2>

</body>

</html>

The output <...> proved me wrong in assuming that an isolated scope would break the inheritance chain between its parent directive and its child directives

证明本身是错误的。此行为特定于无模板指令,类似于包含。在上面的代码中 directive1 没有自己的范围,并且 $scope.name = 'Directive1' 设置在根范围内。 directive1directive2 都是用根作用域编译的,因为它们没有模板,也没有自己的作用域。

如果指令有自己的模板,上述假设将是正确的,例如:

  .directive('directive2', function() {
    return {
      template: '<directive3>'
      controller: ['$scope', function($scope) {
        $scope.name = 'Directive2';
      }],
      scope: {}
    };
  })