2013-03-13 88 views
5

从另一个指令内添加指令会导致浏览器挂起。从angularjs中的另一个指令内添加指令

什么即时试图做的是

1)改变编译函数内的自定义元素指令(如<h7></h7>)。通过这样做,浏览器挂起。

代码:

<h7>TEST</h7> 
    animateAppModule.directive('h7', function($compile){ 
     return { 
      restrict:"E", 
      compile:function(tElement, tAttrs, transclude){     
       tElement[0].setAttribute("ng-class", "{selected:istrue}"); 
       return function(scope, iElement, iAttrs){ 
        //$compile(iElement)(scope); 
       } 
      } 
     } 
    }) 

如果我取消这条线//$compile(iElement)(scope);,浏览器挂起。 你可以在这个小提琴http://jsfiddle.net/NzgZz/3/取消注释上述行,看看浏览器挂起。

但是,如果我在h7指令中有模板属性,浏览器挂起不会发生,如此小提琴中所示。 http://jsfiddle.net/KaGRt/1/

在总体什么IM想要实现

我想agument模板,用induvidual指令的帮助,新的功能。像装饰者模式的东西。 我在指令链中的指令的编译函数内部执行此操作,以便它影响该模板的所有实例。

我试图实现的伪示例。

<xmastree addBaloon addSanta></xmastree> 

1)说xmastree有一个模板 - <div class="xmastree" ng-class={blinks:isBlinking}></div>

2)说addBaloon有一个模板<div class="ballon" ng-class={inflated:isinflated}></div> 然后,addBaloon编译功能应增加从步骤1的模板是这样的

<div class="xmastree" ng-class={blinks:isBlinking}> 
    <div ng-repeat = "ballon in ballons"> 
     <div class="ballon" ng-class={inflated:isinflated}></div> 
    </div> 
</div> 

3)说addSanta有一个模板<div class="santa" ng-class={fat:isFat}></div> 然后,addSanta编译功能应增加从步骤2的模板,像这样

<div class="xmastree" ng-class={blinks:isBlinking}> 
    <div ng-repeat = "ballon in ballons"> 
     <div class="ballon" ng-class={inflated:isinflated}></div> 
    </div> 
    <div ng-repeat = "santa in santas"> 
     <div class="santa" ng-class={fat:isFat}></div> 
    </div> 
</div> 

所有的编译后,如果我运行从对具有合适性能的范围第三步得到的模板,我应该能够得到HTML。

+1

嗨,根据你的伪示例做成plunk。也许它会有所帮助。 http://plnkr.co/edit/ye5yqqSjyKqxTbDBckl3?p = preview – Artem 2013-04-19 03:16:33

+0

当您在当前dom元素上调用$ compile时,您正在进入infinte循环,并且您没有模板属性。文档中有一行提到关于本身不运行$ compile的问题。 – 2013-07-27 21:51:34

+0

这可以帮助你:http://www.bennadel.com/blog/2471-Delegating-Nested-Directive-Behavior-To-Parent-Directive-In-AngularJS.htm – 2013-12-06 04:37:11

回答

3

调用$compile对指令本身的元素将导致相同的指令再次运行,然后重复该过程 - 永远。在很多指令的角度源代码中,你可以看到他们处理这种情况是这样的:$compile(element.contents())(scope);使用element.contents()而不仅仅是element()。这意味着元素中的所有内容都被编译,并且指令/数据绑定被注册,并且不会创建循环。

如果您确实需要$compile元素本身,可以在编译之前完全替换原始元素或从中删除原始指令(删除属性,更改节点类型等)。

相关问题