Pipo
Pipo

Reputation: 5821

Add directive inside other directive in directive definition

My mind is melting while trying to nest directives into each other or to say it better: to re-use an existing directive inside the definition of another directive.

Say I have an existing HTML markup like this:

<a class="class1 class2" href="#link1" data-important="data1">Test</a>

I now want to add new functionality to this existing markup with a custom directive myDirective:

<a class="class1 class2" href="#link1" data-important="data1" my-directive>Test</a>

It doesn't matter what myDirective does, but I want to re-use the ngClick functionality. Normally I would replace the markup with a new template, but I don't know all classes, attributes, etc. beforehand. What I really need is a way to append ngClick. I tried something like this, but it didn't work:

// inside myDirective
compile: function (element, attrs) {
  element.attr('ng-click', 'customFunction()');
}

So I do it this way now:

// inside myDirective
link: function(scope, element, attrs, someCtrl) {
  element.bind('click', function() {
    someCtrl.customFunction();
    scope.$apply();
  });
}

This works but

Any help?

Upvotes: 0

Views: 99

Answers (2)

Jonathan Rowny
Jonathan Rowny

Reputation: 7588

The first way you tried won't work because angular needs to compile to recognize directives. The second way you tried is pretty routine, but you should not have to use scope.$apply(), depending on what you're doing.

Also, setting the attribute of ng-click and then re-compiling would be a bit risky because someone using your directive wouldn't know that it will override an ng-click that they add later on. @kamilkp's answer prevents that, but then that means customFunction also won't fire. It also means double-compiling your element and any directives attached to it.

If you just attach the click handler, an ng-click still works on the element in addition to customFunction firing.

Upvotes: 1

kamilkp
kamilkp

Reputation: 9800

You would have to recompile the entire element like this:

directive('myDirective', ['$compile', function($compile){
    return{
        compile: function (element, attrs) {
           return {
               pre: function($scope, $element, $attrs){
                  if(typeof $attrs.ngClick === "undefined"){
                      $element.attr('ng-click', 'customFunction()');
                      $compile($element)($scope);
                  }
               }
           };
        }
    };
}]);

Upvotes: 1

Related Questions