使用 ngRepeat 和替换根元素的指令:true [英] Directive with root element with ngRepeat and replace: true
问题描述
有人可以解释以下行为背后的根本原因吗?
如果一个具有隔离作用域 scope: {}
的指令有一个带有 ng-repeat
AND replace: true
的根元素,那么它中断" 隔离作用域,意味着隔离作用域不能从指令内部访问/可见,指令开始从外部作用域接收变量.
这是我可以制作的最低限度可重复的示例:
app.controller('MainCtrl', function($scope) {$scope.name = 'MainCtrl';});app.directive("foo", function(){返回 {替换:真的,范围: {},模板:<div ng-repeat='item in [1]'>{{name}}</div>",控制器:功能($范围){$scope.name = "foo";}};});
以下视图将呈现MainCtrl":
<foo></foo>
向模板添加一个不可ng-repeat
的根或设置replace: false
会呈现预期的结果foo".
这不仅仅发生在 ng-repeat 上,这似乎发生在任何其他创建像 ng-if
这样的作用域的指令上以及.看起来,这是因为指令的隔离范围被 ng-repeat 的子范围覆盖.由于 replace:true
选项,ng-repeat 成为指令源元素的一部分,即
和 ng-repeat 的子作用域从最终的父作用域 MainCtrl
计算(这似乎是错误的),这会导致整个指令模板绑定到控制器的子作用域,并且针对该作用域评估任何插值.因此,您会看到指令中扩展了主控制器的范围.这似乎是一个错误.
Can someone explain the root cause behind the following behavior?
If a directive with isolate scope scope: {}
has a root element with ng-repeat
AND replace: true
then it "breaks" the isolate scope, meaning that the isolate scope is not accessible/visible from within the directive, and the directive starts receiving variables from the outer scope.
Here's the minimally reproducible example I could make:
app.controller('MainCtrl', function($scope) {
$scope.name = 'MainCtrl';
});
app.directive("foo", function(){
return {
replace: true,
scope: {},
template: "<div ng-repeat='item in [1]'>{{name}}</div>",
controller: function($scope){
$scope.name = "foo";
}
};
});
The following view would render "MainCtrl":
<div ng-controller="MainCtrl">
<foo></foo>
</div>
Adding either a non-ng-repeat
-able root to the template OR setting replace: false
renders the expected result "foo".
It does not just happen for ng-repeat, this seems to happen for any other directives that creates a scope like ng-if
as well. And it seems like, this is because the directive's isolated scope gets overwritten by the ng-repeat's child scope. And because of replace:true
option ng-repeat becomes a part of the directive source element i.e <foo></foo>
and the child scope of ng-repeat is calculated from the ultimate parent scope MainCtrl
(Which appears to be wrong) and this causes the entire directive template to be bound to the child scope of controller and any interpolations are evaluated against that scope. Hence you see main controller's scope being expanded in the directive. This seems like a bug.
这篇关于使用 ngRepeat 和替换根元素的指令:true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!