Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can two directives (that are not nested in HTML) communicate with each other?

im pretty new to angularJS and I got a question (hope it's not that dumb):

I got 2 directives (not nested):

<div directive1></div>
<div directive2></div>

Now i want the directives to talk to each other with a controller (Ive defined a 'controller: ' in directive1):

myApp
    .directive('directive2', function () {
        return {
            require: "^directive1",

            link: function (scope, element, attrs, directive1Ctrl) {
                directive1Ctrl.doSomething();
            }
        };
    });

BUT Im always getting 'Controller not Found' Exception.. (Im not that sure about the ^ cause its only for searching upwards through parents).
Is it not possible to use the Controller defined in directive1 from directive2 if theyre not nested? Do i have to use a 'seperate' Controller which both require to work with each other?

like image 585
Jenson Avatar asked May 17 '13 12:05

Jenson


2 Answers

Do i have to use a 'seperate' Controller which both require to work with each other?

This is close. The standard way to share data and functionality between different pieces of your application (two controllers, two directives, a directive and a controller, etc.) is to provide that data or functionality in a service. This service can then be injected into any application component that requires it.

In your case, you could create a service that provides the doSomething function and inject it into both directive1 and directive2.

like image 121
Noah Freitas Avatar answered Nov 04 '22 13:11

Noah Freitas


if you set require: "^directive1", your directive 2 must be in directive 1:

<div directive1>
    <div directive2></div>
</div>

You can also use "?directive1" which makes it optional.

Simple put: there are two types of controllers: directive controllers and the normal ones.

With controllers you can set values in the scope that will be updated in the view. This is a plunkr with one controller and two directives: http://plnkr.co/edit/IicvQfuv8LMOb4iVQen5

var app = angular.module('plunker', []);

app.directive('directive1', function() {
    return {
        restrict: 'A',
        replace: true,
        template: '<span>{{bar}}</span>'
    }
});

app.directive('directive2', function() {
  return {
      restrict: 'A',
      replace: true,
      template: '<b>{{bar}}</b>'
  }

});

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.foo ="layla";
  $scope.bar ="hello";
});

and the html:

<body ng-controller="MainCtrl">
  this is directive1: <div directive1>{{foo}}</div>.
  <br />
  this is directive2: <div directive2>{{foo}}</div>.
  Hello {{name}}!
</body>

Notice that directives are new elements that your browser can parse. They are an extension of HTML whose behaviour you defined in the app.directive() part.

When AngularJS finds {{foo}} it'll bind it to a scope that can be modified with the closer controller that has access to that scope. In this case, MainCtrl. You could also put MainCtrl in a <div ng-controller="MainCtrl">...</div>

With your code you get controller not found because it's going up the tree to find a controller named directive1Ctrl, which never happens.

like image 3
Eduard Gamonal Avatar answered Nov 04 '22 14:11

Eduard Gamonal