В 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) При использовании 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>

Результатом обоих кодов является - я Directive1, который показывает, что директива3 наследует область действия директивы 1 (она не будет получать доступ к области директивы2, поскольку она имеет изолированную область), что оказалось неправильным, если предположить, что изолированная область цепочку наследования между его родительской директивой и ее дочерними директивами, и, таким образом, ни одна из ее дочерней директивы не сможет получить доступ к сфере действия любой из ее предков.

Я что-то упустил здесь, или моя концепция наследования сферы совершенно неверна?

+1
27 окт. '17 в 15:50
источник поделиться
2 ответа

Выход <...> доказал, что я ошибаюсь, полагая, что изолированная область будет нарушать цепочку наследования между ее родительской директивой и ее дочерними директивами

Само доказательство ошибочно. Это поведение специфично для директив без шаблонов и похоже на переключение. В коде выше directive1 не имеет собственной области действия, а $scope.name = 'Directive1' задается в корневой области. И оба directive1 и directive2 скомпилированы с корневой областью, потому что у них нет шаблонов и нет собственных областей.

Указанное предположение будет правильным, если директивы имеют свои собственные шаблоны, например:

  .directive('directive2', function() {
    return {
      template: '<directive3>'
      controller: ['$scope', function($scope) {
        $scope.name = 'Directive2';
      }],
      scope: {}
    };
  })
+1
27 окт. '17 в 16:10
источник

Используйте 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>
0
27 окт. '17 в 16:05
источник

Связанные вопросы


Похожие вопросы

Посмотрите другие вопросы по меткам или Задайте вопрос