12

I already know that you can set up a controller within a directive, and that other directives can call the functions on that controller. Here's what my current directive looks like:

app.directive("foobar", function() {
  return {
    restrict: "A",
    controller: function($scope) {
      $scope.trigger = function() {
        // do stuff
      };
    },
    link: function(scope, element) {
     // do more stuff
    }
  };
});

I know that I could call it like this:

app.directive("bazqux", function() {
  return {
    restrict: "A",
    require: "foobar",
    link: function(scope, element, attrs, fooBarCtrl) {
        fooBarCtrl.trigger();
    }
  };
});

However, I want to be able to call trigger from any directive, not just my own custom ones, like this:

<button ng-click="foobar.trigger()">Click me!</button>

If that doesn't work, is there a way to bring in a third directive to make it happen? Like this?

<button ng-click="trigger()" target-directive="foobar">Click me!</button>

Thanks!

3 Answers 3

8

Sounds like you need an angular service. http://docs.angularjs.org/guide/dev_guide.services

This will allow you to share functionality across directives.

Here's a similar question: Sharing data between directives

Sign up to request clarification or add additional context in comments.

5 Comments

I've used services, but I have no idea how I'd use them to facilitate cross-directive communications. Can you provide an example?
Sure, can you dump both your directives that need to be communicated with one another in a jsfiddle?
I would not use the rootScope method if that's what you're doing. I posted an edit to my question that shows a similar question asked.
It would be great to see an example which does it like in this post: fdietz.github.io/recipes-with-angular-js/directives/… but without the need of an attribute, but instead with an own directive.
An issue here is it's a singleton like which is what service are in Angular. If you want to keep the data isolated to the area in the application, you might consider using a master controller for the area of the application you're in with isolated scope and 'require' attribute from the children referring that controller. It might be more tightly coupled but it defines an API through a controller and you can have multiple instances of the same directive not sharing their state. See example.
6

One simple way of accomplishing application-wide communication between any components would be to use global events (emitted from the $rootScope). For example:

JS:

app.directive('directiveA', function($rootScope)
{
    return function(scope, element, attrs)
    {
        // You can attach event listeners in any place (controllers, too)

        $rootScope.$on('someEvent', function()
        {
            alert('Directive responds to a global event');
        });
    };
});

HTML:

<button ng-click="$emit('someEvent')">Click me!</button>

Here you're emitting an event from the child scope but it will eventually reach the $rootScope and run the previous listener.

Here's a live example: http://plnkr.co/edit/CpKtR5R357tEP32loJuG?p=preview

3 Comments

Don't do this, it will pollute rootscope, create a service or maybe require the directive.
pointing out $rootScope gotchas: jsfiddle.net/drzaus/a1gm7q4u basically like @WillemD'haeseleer said, you may get side effects sending things up to / down from $rootScope if other "isolated" scopes are listening to the same thing (i.e. repeated directive or controller)
Agreed, downvoted because this answer is accepted but is not as good as some of the others.
1

When talking on irc it turned out that the communication is unnecessary:

I've got an attribute-restricted directive which performs some DOM manipulation on its parent element when it's "triggered"

A solution is to keep the logic inside the same directive and just to apply the dom changes to the parent. http://jsfiddle.net/wt2dD/5/

scope.triggerSmthOnParent = function () {
    element.parent().toggleClass('whatewer');
}

1 Comment

IMO, ng-class should be used in most (99%) circumstances when class names need to be added.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.