重复在一个跨越里面不工作?

好吧,这可能看起来有些深奥,但我正在尝试用我写的指令解决特定问题:https://github.com/michaelbromley/angularUtils/issues/37

这是一个正在发生的简化版本。

这工作:

我有一个指令,通过在编译阶段动态添加一个ng-repeat属性到元素来委托ng-repeat,然后编译该元素:

myApp.directive('repeatDelegator', function($compile, $timeout) {
  return {
    compile: function(element, attrs){
        attrs.$set('ngRepeat', attrs.repeatDelegator); //Add ng-repeat to the dom
        element.removeAttr('repeat-delegator'); // remove the repeat-delegator to prevent infinite recursion of compilation

        var compiled =  $compile(element, null);
        return function(scope, element, attrs){
            compiled(scope);
        };
      }
   }
});

这是如何调用该指令:

<ul>
    <li repeat-delegator="item in items">{{item}}</li>
</ul>

这工作正常 - 请参阅这里的第一个示例:http://plnkr.co/edit/oWd3rGAulsxoeSqffxMU?p=preview

但是,当repeat-delegator放入其他使用transclusion的指令中时,它不起作用。

这不起作用。 为什么?

这是一个基本的指令,它只会导致包含:

myApp.directive('transcluder', function() {
    return {
        restrict: 'AE',
        transclude: true,
        scope: {},
        template: '<div ng-transclude></div>'
      };
});

所以当我们在这个转换中调用repeat-delegator指令时,它会失败并且什么也没有显示出来:

<transcluder>
    <ul>
        <li repeat-delegator="meal in meals">{{meal}}</li>
    </ul>
</transcluder>

这在第二个例子中说明:http://plnkr.co/edit/oWd3rGAulsxoeSqffxMU?p=preview

到目前为止我所知道的是:

我花了一些时间在执行Angular.js源代码时尝试弄清楚它为什么会在该内容中失败,但我无法理解它的底部。

在破坏的(transcluded)版本中,当我看到正在编译的ngRepeat时,$ scope似乎是正确的(它是主控制器$ scope的子$ scope,因为transclusion导致创建一个新的子$ scope) 。 您可以在控制台中输入“scope.items”并查看项目列表。

我猜这样的事情正在发生:

  • transcluder指令首先被编译,因为它在DOM树中较高,所以首先遇到它。
  • 该转换导致指令的子节点被从DOM中移除并克隆到$template var中,以便稍后插入到DOM中。
  • 也许这会导致ng-repeat针对<li>..</li>节点的克隆进行编译,该节点实际上从未连接回DOM?
  • 虽然我不确定。 这是一个非常棘手的问题,任何帮助将非常感谢!


    好吧,经过一天在开发工具中攻击Angular.js源代码后,我发现这里出了什么问题,上面的猜测基本上是正确的。

    问题在于repeat-delegator指令会针对分离的克隆进行编译,所以有效地将重复ng元素添加到丢失的DOM块中,这些元素永远不会附加回页面主体。

    解决方案非常简单:将repeat-delegator委托的ng-repeat的编译移动到链接函数中(而不是在编译阶段,即原来的位置)。

    这样做意味着当ng-repeat被编译时,它会针对正确的DOM节点完成,该节点现在已安全地连接到transcluded指令下的DOM。

    myApp.directive('repeatDelegator', function($compile, $timeout) {
        return {
          compile: function(element, attrs){
              attrs.$set('ngRepeat', attrs.repeatDelegator); //Add ng-repeat to the dom
              element.removeAttr(attrs.$attr.repeatDelegator); // remove the repeat-delegator to prevent infinite recursion of compilation
    
              return function(scope, element, attrs){
                  var compiled =  $compile(element);
                  compiled(scope);
              };
          }
       }
    });
    
    链接地址: http://www.djcxy.com/p/95237.html

    上一篇: repeat not work inside a transclusion?

    下一篇: Check to see if element exists after DOM is ready