-1

Let's say I have the following two directives:

angular.module('test').directive('apiDirective', function (){
  return {
    restrict: 'A',
    controller: function () {
      this.awesomeFunction = function () {
        console.log("CHECK ME OUT BEING AWESOME");
      }
    }
  }
});

angular.module('test').directive('consumerDirective', function ($compile) {
  return {
    restrict: 'E',
    require: '?apiDirective',
    transclude: true,
    link: function (scope, element, attrs, controller, transcludeFn) {
      console.log('preLink controller: ', controller);
      transcludeFn(scope, function (tElem, tScope) {
        if (attrs.apiDirective === undefined) {
          element.attr('api-directive', '');
          $compile(element)(scope);
        }
        element.html(tElem);
        $compile(tElem)(tScope);
      });

      scope.consumerFunction = function () {
        console.log('trying to consume the awesome', controller);
        controller.awesomeFunction();
      }
    }
  }
});

And the following html:

<consumer-directive ng-click="consumerFunction()"/>

When the directive loads transclusion occurs as expected, setting the controller to be my apiDirective Controller. However in the consumerFunction, the controller is always null. Why? I suspect it has something to do with the second compile?

Removing the second compile entirely causes the directive to render nonfunctionally. Why?

What is going on, and how do I fix it without inlining the attribute level controller on the directive by hand?

plnkr demo: http://plnkr.co/edit/Lbh7T9FRg3nS6ERW4HtA

Abraham P
  • 15,029
  • 13
  • 58
  • 126
  • Can you explain what you are trying to achieve? Why are you recompiling the `element`, and why are you recompiling the (non-existent, in your example) transcluded content? – New Dev Mar 31 '15 at 00:17
  • The apiDirective generates modals, its a thin layer of abstraction wrapped around angular-bootstrap modal, it accepts a template, controller, and callback); The consumerDirective generates a specific kind of modal (a picker in our case). The idea is that you could have arbitrary child dom which causes the consumerFunction to run and trigger the picker creation with data from the current scope. I can't really paste any specific code because it is proprietary, but I'd be happy to answer any further questions you have. – Abraham P Mar 31 '15 at 00:39
  • Can you post some sensible (if not exact) code? I don't understand what should happen and what doesn't. And you haven't answered what you were trying to achieve by recompiling... Also, it seems "broken" (even of this is the intent to call a function defined by the directive from outside of it - I'm referring to `ng-click="consumerFunction()"` – New Dev Mar 31 '15 at 00:44

1 Answers1

0

You need to have an instance of the directive you are looking for a controller of if you want to find something (require only returns instances of controller, not a factory of functions). Working example: http://plnkr.co/edit/XP3dV456M0No6nbx2zOW?p=preview

<body>
   <div ng-app="test">
      <consumer-directive api-directive ng-click="consumerFunction()">aaa</consumer-directive>
  </div>

Tahsis Claus
  • 1,879
  • 1
  • 15
  • 27