3
votes

I'm trying to chain two nested directives that both use isolated scopes.

<div ng-controller="myController">
    <my-dir on-done="done()">
        <my-dir2 on-done="done()">
        </my-dir2>
    </my-dir>  
</div>

I would like the second directive (my-dir2) to call the done() function of the first directive (my-dir) which in turn would call the controller one.

Unfortunately I don't know how to make the second directive access the callback of the first directive (so far the second directive is looking inside the high level controller, bypassing the first directive).

I think one could possibly make use of "require" but I can't since the two directives are not related (I want to use my-dir2 inside other directives not only my-dir).

To make it clear : I don't want to use require because it means that there would be a dependency of myDir on myDir2. My point is : I want to be able to reuse myDir2 inside others directives. So I don't want myDir2 to be based on myDir but I do want to inform the upper directive (myDir) when something is done (like in a callback in js).

I have made a plunker : as you can see in the javascript console, my-dir2 is calling directly the done function from the high level controller.

Does anyone has a clean way to deal with that kind of situation ?

Thanks

2

2 Answers

0
votes

Update:

to be able write directives that are independent of each other you need to use events:

  1. use $emit('myEvent', 'myData') to fire an event that will be handled by scopes that are upward in the hierarchy.
  2. use $broadcast('myEvent', 'myData') to fire an event that will be handled by scopes that are downward in the hierarchy.
  3. to handle the event that was fired by $emit or $broadcast use $on('myEvent', function(event, data){\\your code})

P.S.: in your case the $emit won't work because both directives scopes are on the same level in the hierarchy so you will need to use $rootScope.$broadcast('myEvent' \*, myData*\); I've updated my plunker to reflect the needed changes http://plnkr.co/edit/eTkO6sk6hpuYPnCjlSKn?p=info

The following will make inner directive dependent on the outer directive:

basically to be able to call a function in the first directive you need to do some changes:

  1. add require = '^myDir' to myDir2
  2. remove the onDone from myDir2 and keep the isolated scope scope:{}
  3. add controller parameter to link function in myDir2 link: function(scope,element,attrs,controller)
  4. in myDir1 controller change the definition of the done function from $scope.done to this.done
  5. call controller.done() in myDir2

here is a plunker with the needed changes http://plnkr.co/edit/eTkO6sk6hpuYPnCjlSKn

0
votes

I think you can do something like these: angular.element('my-dir').controller('myDir').done();

give a try!