4

有关指令的 Angular 文档中,有这样一段:

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

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

4

2 回答 2

2

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

<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

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

$rootScope
└controller scope
  └ng-repeat scope
    └widget contents
widget scope
于 2013-07-07T19:49:54.777 回答
1

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

<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';
        }
    }
});

嵌入确保指令中的 {{name}} 引用“foo”而不是“bar”。

于 2013-07-09T08:06:53.110 回答