8

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.

tgkokk
  • 1,610
  • 1
  • 13
  • 16
  • Just out of curiosity, Why are you using the same controller for both the directives? – callmekatootie Jun 05 '13 at 08:48
  • I need to share some data between them. Do you know a better way to do this? – tgkokk Jun 05 '13 at 08:52
  • Yes - Services! `$rootScope` too does the trick but will be frowned upon. http://stackoverflow.com/questions/9293423/can-one-controller-call-another-in-angularjs - this is all that you need to know to communicate between controllers. – callmekatootie Jun 05 '13 at 08:55
  • Great! Post it as an answer and I'll be happy to accept it. – tgkokk Jun 05 '13 at 09:00

2 Answers2

5

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.

Community
  • 1
  • 1
callmekatootie
  • 10,989
  • 15
  • 69
  • 104
4

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/

Oliver
  • 4,471
  • 2
  • 21
  • 18
  • But yeah, if your directives are siblings, services are a solution. – Oliver Jun 05 '13 at 09:06
  • Good solution and I'll definitely use it when the directives don't have to be siblings. For this case, callmekatootie's is better IMHO. – tgkokk Jun 05 '13 at 09:19