0

Say I have the following two directives in my page:

<todos></todos>
<calendar></calendar>

The file structure is set up as follows:

/todos

  • todo-controller.js

  • todo-directive.js

  • todo-view.html

/calendar

  • calendar-controller.js

  • calendar-directive.js

  • calendar-view.html

Since these two directives are "on the same level" and one is not contained inside the other this doesnt allow me to use the require syntax in my directive to do something like this in the todo controller:

CalendarCtrl.foo()

Right now Im using lots of broadcast and on listeners and its getting very messy. How do I more easily share functionality between these and keep my file structure the same?

Rigil
  • 609
  • 3
  • 8
  • 15
  • Make a `/scheduling` module which `/todos` and `/calendar` are sub-modules of. Then you could have schedule-service.js. Though I would let the controller talk to the scheduling-service and then have the directives scope to the controller. – Cory Silva Dec 19 '14 at 06:55
  • Just use common service which you inject in both directives. – dfsq Dec 19 '14 at 06:57
  • possible duplicate of [Directive-to-directive communication in AngularJS?](http://stackoverflow.com/questions/16628616/directive-to-directive-communication-in-angularjs) – New Dev Dec 19 '14 at 06:58
  • My calendar controller has objects that must live inside the scope of calendar controller. That being the case, is using a service still possible? – Rigil Dec 19 '14 at 07:16
  • 1
    You can move those objects into the service, and from calendar controller expose this.getObjects = ScheduleService.getObjects, and in your view use {{CalendarController.getObjects()}} – Robert Balicki Dec 19 '14 at 07:24

2 Answers2

1

The file/directory structure does not matter. Your directives file(calendar-directive.js, todo-directive.js) should get properly loaded on the browser, which you probably would be loading through index.html (script tag). You have to just properly defined the modules, its dependencies, and the directives. For example

angular.module('mainModule', []);

angular.module('mainModule').directive('calendar' ['service1', 'service2', function(service1, service2) {

}]);

angular.module('mainModule').directive('todo' ['service1', 'service2', function(service1, service2) {
return {
restrict: 'AE', 
...
require: '^calendar', 
...
link : function($scope, element, attrs, CalendarCtrl) {
 CalendarCtrl.foo();
}
}
}]);

To use the directive in another directive, you have to appropriately use 'require' in your DDO (directory definition object). Its controller would be injected into your link function as the fourth argument. Note here that the both the directive are in the same module, 'mainModule', and their directory structure does not matter.

  • How would I require ^calendar from todo if todo is not inside or below calendar? – Rigil Dec 19 '14 at 07:15
  • You Communicate between the controllers of your directives with Services... A Angular Service is a singleton that can store data and be accessed from any scope of your controllers... Well you could use service, or factory... – Dennis Weidmann Dec 19 '14 at 07:18
  • @Neo so if I wanted to set some scope variable in calendar controller from todo, I can do that using a service? eg. inside the todo controller I could say TheNewService.setSomeCalenderScope('my value') and it would get applied to the scope of calendar controller? – Rigil Dec 19 '14 at 07:21
0

If you want to just share a value between two controllers, you can do it with a service, or a factory...

If you want to trigger an event in a second Controller, invoked on a first Controller, you can define an event and broadcast it through your $rootScope with the Data you want to send. In my example my event is named 'changeMyEntryEvent' and data is a string 'myNewEntry'.

app.controller('firstController', function ($scope,$rootScope) {

       $rootScope.$broadcast('changeMyEntryEvent', 'myNewEntry');

});

app.controller('secondController', function ($scope,$rootScope) {

       $rootScope.$on('changeMyEntryEvent', function (event, data) {
              //Execute your code on second Controller, triggered by firstController
       });

});
Dennis Weidmann
  • 1,942
  • 1
  • 14
  • 16
  • Im using lots of broadcasts and on listeners as it is and Im trying to stop doing that as its getting messy. – Rigil Dec 19 '14 at 07:31
  • Its getting messy? :-) well ok but I don't think that there is another Solution to trigger an event on another controller?!? – Dennis Weidmann Dec 19 '14 at 07:35
  • Thats a bummer because the way I have it setup up now the directives are self contained and I can drop them into any route on any page without having to worry about dependencies. Of course the problem Im faced with is all the broadcast/on listeners which is becoming a hassle to maintain. – Rigil Dec 19 '14 at 09:03