Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add directive from inside another directive in angularjs

Tags:

angularjs

Adding directive from inside another directive, makes the browser to hang.

What im trying to do is

1) Alter an custom element directive (like <h7></h7>) inside the compile function. By doing this the browser hangs.

code:

<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);
                }
            }
        }
    })

If i uncomment this line //$compile(iElement)(scope);, the browser hangs. You can uncomment the above said line in this fiddle http://jsfiddle.net/NzgZz/3/ to see the browser hanging.

However the browser hanging is not happening if i have template property in the h7 directive, as shown in this fiddle. http://jsfiddle.net/KaGRt/1/.

In overall what im trying to achieve is

I want to agument the template, with new functionalities with help of induvidual directives. Somthing like decorator pattern. I'm doing this inside the compile function of an directive which is in the directive chain so that it affects all that instances of that template.

Pseudo example of what I'm trying to achieve.

<xmastree addBaloon addSanta></xmastree>

1) Say xmastree has a template - <div class="xmastree" ng-class={blinks:isBlinking}></div>

2) Say addBaloon has a template <div class="ballon" ng-class={inflated:isinflated}></div> Then, addBaloon compile function should augment the template from step1 to something like this

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

3) Say addSanta has a template <div class="santa" ng-class={fat:isFat}></div> Then, addSanta compile function should augment the template from step2 to something like this

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

After all the compilation, if i run the template derived from step3 against a scope with suitable properties, i should be able to get the HTML.

like image 882
Rajkamal Subramanian Avatar asked Oct 21 '22 15:10

Rajkamal Subramanian


1 Answers

Calling $compile on the element of the directive itself will cause the same directive to run again, which then repeats that process - forever. In the angular source code of many directives, you can see that they handle this situation like this: $compile(element.contents())(scope); using element.contents() rather than just element(). That means that everything inside of the element is compiled and the directives/data-bindings are registered and no loop is created.

If you do need to $compile the element itself, either replace the original element entirely or remove the original directive from it (remove the attribute, change node type, etc) before compiling.

like image 100
m59 Avatar answered Oct 29 '22 19:10

m59