在有关指令的 Angular 文档中,有这样一段:
然而,隔离作用域产生了一个新问题:如果一个嵌入的 DOM 是小部件隔离作用域的子对象,那么它将无法绑定到任何东西。由于这个原因,在小部件为其局部变量创建隔离范围之前,被嵌入的范围是原始范围的子级。这使得 transcluded 和 widget 隔离范围兄弟姐妹。
有人可以解释为什么“如果嵌入的 DOM 是小部件隔离范围的子级,那么它将无法绑定到任何东西”?
在有关指令的 Angular 文档中,有这样一段:
然而,隔离作用域产生了一个新问题:如果一个嵌入的 DOM 是小部件隔离作用域的子对象,那么它将无法绑定到任何东西。由于这个原因,在小部件为其局部变量创建隔离范围之前,被嵌入的范围是原始范围的子级。这使得 transcluded 和 widget 隔离范围兄弟姐妹。
有人可以解释为什么“如果嵌入的 DOM 是小部件隔离范围的子级,那么它将无法绑定到任何东西”?
想象一下,你有一些这样的标记:
<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
本次演讲中提到的另一个微妙之处是,如果您的嵌入内容的范围是指令的子范围,那么该指令可能会破坏嵌入内容试图在父范围中引用的任何变量。例如:
<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”。