使用 ngRepeat 和替换根元素的指令:true [英] Directive with root element with ngRepeat and replace: true

查看:33
本文介绍了使用 ngRepeat 和替换根元素的指令: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".

Plunker

解决方案

这不仅仅发生在 ng-repeat 上,这似乎发生在任何其他创建像 ng-if 这样的作用域的指令上以及.看起来,这是因为指令的隔离范围被 ng-repeat 的子范围覆盖.由于 replace:true 选项,ng-repeat 成为指令源元素的一部分,即 </foo> 和 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".

Plunker

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆