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



我有两个例子支持上述陈述 -

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) 使用控制器As(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>

两个代码的输出都是 - 我是指令 1,这表明指令 3 继承了指令 1 的范围(它不会访问指令 2 的范围,因为它有一个隔离的作用域),这证明我错误地假设隔离作用域会破坏其父指令和子指令之间的继承链,因此它的子指令都无法访问其任何祖先 指令的范围。

我在这里遗漏了一些东西,还是我的范围继承概念完全错误?

输出<...>证明我错误地假设隔离的作用域会破坏其父指令和子指令之间的继承链

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

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

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

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

注意:scope:true 将从父级继承属性,但 scope:{} 不会从父级继承属性。

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

最新更新