【问题标题】:AngularJS - Explain why transcluded scopes must be siblings of an isolate scopeAngularJS - 解释为什么嵌入的范围必须是隔离范围的兄弟
【发布时间】:2013-07-07 15:12:49
【问题描述】:

Angular docs on directives中,有这么一段:

然而,孤立的作用域产生了一个新问题:如果一个嵌入的 DOM 是 小部件隔离范围的孩子,那么它将无法绑定 对任何事情。由于这个原因,被嵌入的范围是 原始范围,在小部件为其创建隔离范围之前 局部变量。这使得嵌入和小部件隔离范围 兄弟姐妹。

谁能解释一下为什么“如果嵌入的 DOM 是小部件隔离范围的子级,那么它将无法绑定到任何东西”?

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    想象一下你有一些这样的标记:

    <html ng-app="myApp">
      <body>
        <div ng-controller="myController">
          <div ng-repeat="item in items">
            <div my-widget>
              {{item.name}}
            </div>
          </div>
        </div>
      </body>
    </html>
    

    这设置了一个范围树($rootScope -> 控制器范围 -> ng-repeat 范围 -> 小部件范围)。现在说你的控制器里面有一些东西:

    function myController($scope) {
      $scope.items = [
        {name: 'Stella Artois'},
        {name: 'Red Stripe'}
      ];
    }
    

    您可以从任意多个级别的范围中读取值,因为它们使用原型继承从彼此继承。 {{item}} 不存在于小部件范围内,但它存在于父级 ng-repeat 范围内,因此可以找到它。

    如果您使用隔离作用域,您将获得一个不会从任何东西继承的全新作用域。因此,如果 my-widget 使用 scope: {} ,则作用域树看起来更像:

    $rootScope
    └controller scope
      └ng-repeat scope
    widget scope
    

    然后在双卷曲中,“item”是未知的。使用嵌入,您可以将范围设置为兄弟,如下所示:

    $rootScope
    └controller scope
      └ng-repeat scope
        └widget contents
    widget scope
    

    【讨论】:

      【解决方案2】:

      in this talk 提到的另一个微妙之处是,如果您的转入内容的范围是指令的子范围,那么该指令可能会破坏转入内容试图在父范围中引用的任何变量。例如:

      <body ng-controller="MainCtrl">
      <my-directive>{{ name }}</my-directive>
      </body>
      

      JS:

      app.controller("MainCtrl", function($scope) {
          $scope.name = 'foo';
      });
      
      app.directive("myDirective", function() {
          return {
              scope: {},
              transclude: true,
              template: '<span ng-transclude></span>',
              controller: function($scope) {
                  $scope.name = 'bar';
              }
          }
      });
      

      Transclusion 确保指令中的 {{name}} 引用 'foo' 而不是 'bar'。

      【讨论】:

      • 对我来说,让它被破坏更有意义。如果我可以在没有嵌入的情况下破坏它,为什么我会突然想要改变这种行为,只是因为我嵌入了它?我可能出于某种原因试图破坏它。
      • 我认为这个假设是嵌入更多地用于库和可重用组件。您可能不想担心与您正在使用的所有各种库的名称空间冲突,而嵌入会为您解决这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 2013-03-15
      相关资源
      最近更新 更多