9

I am having trouble catching an event which is sent like this:

document.body.dispatchEvent(event);

The directive below is on a div, inside the body:

.directive('myDirective',function(){
  return {
    restrict: 'A',
    link: function(scope, element, attrs, pageCtrl){

      element.bind('myEvent', function(){
        console.log('caught my event!');
      });
    }
  };
});

This works if the event is sent with triggerHandler on the div.

event = new Event('myEvent');
elem.triggerHandler(event);

How can I catch a custom event on the document body inside a directive?

Update: This is for use in a Cordova app, with an existing plugin, which dispatches events on document.body. So is there another way I can catch those events in a directive on a div?

1
  • 1
    First, is it necessary in your case to use the DOM to emit and respond to events? I ask because there are a few ways in Angular itself to communicate across your app, including Angular's own internal event system. Commented May 6, 2014 at 23:55

1 Answer 1

7

The problem is that events bubble, meaning when you dispatch the event from document.body, it propagates up through its ancestors. Since it doesn't travel down through its descendants, your directive's event listener is never fired.

You can, however, catch the event on body and fire to your div using Angular's internal event system.

Create two directives

One to decorate the body element with the following behavior:

  • catches the Cordova event, then...
  • broadcasts an Angular-internal event from rootScope

.directive('bodyDirective',function($rootScope){
  return {
    restrict: 'A',
    link: function(scope, element, attrs){
      element.bind('myEvent', function(){
        $rootScope.$broadcast('cordovaEvent');
      });
    }
  };
})

... and another to decorate the div with behavior that will catch the Angular event:

.directive('divDirective', function(){
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      scope.$on('cordovaEvent', function(){
        // do something here
      }); 
    }
  } 
})

Plunker (you must view the preview in a separate window and watch console there)

Sign up to request clarification or add additional context in comments.

3 Comments

@mark, Thanks. That is absolutely the problem I am facing. Please see my update.
Updated my answer with a way to catch to catch the event on your div
Your update works great. And thanks for the console tip on Plunker.

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.