How to use a controller for two directives?

Problem

I have this code:

JS:

angular.module("module")
  .controller("fooController", ["$scope", function($scope) {
    ...
  })
  .directive("foo", function() {
    return {
      restrict: "E",
      controller: "fooController",
      link: function($scope, $element, $attrs) {
        // Do some things with the scope of the controller here
      }
    }
  })
  .directive("bar", function() {
    return {
      restrict: "E",
      require: "fooController",
      link: function($scope, $element, $attrs) {
         // Nothing yet
      }
    }
  });

HTML:

<html>
  <head>
    <!-- Scripts here -->
  </head>
  <body ng-app="module">
    <foo/>
    <bar/>
  </body>
</html>

Directive foo works, but directive bar throws an error: No controller: fooController.

How can I fix this while maintaining my current structure (Controller isn't inside the HTML, but is used by the directives, bar is outside foo and share the same controller, while both are modifying its scope)? I read the discussion here, but I couldn't understand how to do it.

Problem courtesy of: tgkokk

Solution

Since your ultimate objective is to communicate between controllers, you need not re-use the same controller across multiple directives (I doubt if re-using would allow you to communicate). Anyway, the best way to go about it would be use services.

Article Can one controller call another? speaks about it in detail, but in simple terms, first create a service:

app.factory('myService', function () {
    var data;
    return {
        getData: function () {
            return data
        },
        setData: function (newData) {
            data = newData;
        }
    };
});

You can then use this service in your controllers and communicate with each controller by using setData() and getData() functions of the service.

Solution courtesy of: callmekatootie

Discussion

You can't require a controller. You can require a directive which is one of the parents of the current directive.

   <foo>
      <bar />
   </foo>

   // in foo
   controller: 'fooController'
   // in bar
   require: '^foo' // ^ means to search it up in the tree

Here bar can require foo and it'll have foo's controller: http://jsfiddle.net/Zmetser/kHdVX/ In this example fooController'll be initialized once.

   <foo />
   <bar />

   // in foo
   controller: 'fooController'
   // in bar
   controller: 'fooController'

Here bar and foo has its on instance of the fooController: http://jsfiddle.net/Zmetser/QypXn/

Discussion courtesy of: Oliver

This recipe can be found in it's original form on Stack Over Flow.