Directive-to-directive communication in AngularJS?

2020-03-01 09:28发布

问题:

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!

回答1:

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



回答2:

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



回答3:

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