3

I have scenario where I want to send a broadcast event in one controller and have the controller for a directive receive the message. The event is sent immediately on controller startup, and the issue is that because the directive is loading the view using templateUrl, it happens asynchronously, so the event is broadcast before the directive controller is intialised. This problem doesn't happen if the view is in the main page body, but I guess there could still be an issue with controller initialisation order.

I am using the following code in my main controller:

$rootScope.$broadcast("event:myevent");

I have reproduced the issue here: http://jsfiddle.net/jugglingcats/7Wf8N.

You can see in the Javascript console that the main controller is initialised before the controller for the directive, and it never sees the event.

So my question is whether there is a way to wait until all controllers are initialised before broadcasting an event?

Many thanks

2
  • Is there any particular reason you are using an event rather than attaching something to the scope? Commented Sep 28, 2013 at 3:27
  • Not really, but I thought about using a service as some people suggest or even just the scope, but couldn't immediately think how this would help given the initialisation sequence in my case. I have accepted kju's answer as this worked for me... Commented Sep 28, 2013 at 7:47

2 Answers 2

1

I have created a working version. I actually feel that it is a very unclean way to do it, but I could not come up with something better: http://jsfiddle.net/7Wf8N/3/

What I did is this: In the directive I added some code which will increase a counter in $rootScope upon initialization. I use a counter because as you said, you want to wait for more than one controller:

$rootScope.initialized = ( $rootScope.initialized||0 ) +1;

In the "RegularCtrl" I added a watch on this counter and if the counter reaches the correct value (everything is initialized) I send the event:

$rootScope.$watch('initialized', function() {
    if ( $rootScope.initialized == 1 ) {
        $rootScope.$broadcast("event:myevent");        
    }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Agree not totally clean but this approached worked for me. Thanks!
1

Are you ng-view? If so, you have the $viewContentLoaded event available. This will fire after all the dom is loaded.

http://docs.angularjs.org/api/ngRoute.directive:ngView

function MyCtrl($scope, $rootScope) {
  $scope.$on('$viewContentLoaded', function() {
      $rootScope.$broadcast('event:myevent');
  });
}

If you aren't using ng-view, you could just set a variable and use data-binding to your directive.

1 Comment

Not using ng-view. I used $watch as per kju's answer in the end.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.