AngularJS : Listen for click events on a button outside of a directive
Asked Answered
L

1

6

I am new to angularjs. I am building an angularjs SPA. The application page has two sections - a buttons area and a application area. The application area is where my views are loaded. The buttons area is the same for each view, hence I do not include it in the views template but rather keep it in the application window. My problem is that I would like the various directives that I load into the application area to respond to clicks in the buttons area. How do I listen to click (or any other event) that originate outside of a directive? Thanks much in advance!

Lockwood answered 24/5, 2014 at 16:22 Comment(0)
P
9

You just need to reference the button and attach an event handler to it.

Example:

app.directive('directiveName', function () {

  return {
    link: function (scope, element, attrs) {

      // Get a reference to the button DOM element
      var buttonDOMElement = document.querySelector('#button1');

      // Wrap it as a jqLite element
      var button = angular.element(domElement);

      var onButtonClick = function () {
        // Do something
      };

      button.on('click', onButtonClick);

      scope.$on('$destroy', function () {
        button.off('click', onButtonClick);
      });
    }
  };
});

Demo: http://plnkr.co/edit/4XvPT8r9USWHnbdu1ZHX?p=preview

Note that event handlers attached like this lives "outside of Angular". This means that if your handler updates for example a scope value that is bound to the view, you need to explicitly tell Angular, or the change will not be reflected until the next time something triggers the digest loop.

For this you can use $apply:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.

Example:

var onButtonClick = function () {
  scope.$apply(function () {
    // Do something
  });
};
Paternal answered 24/5, 2014 at 17:52 Comment(4)
Thanks you very much! I appreciate this immensely. Thank you for the lesson in using the $apply() function. God bless, my friend.Lockwood
Hey, I tried your suggestion and it worked well but only when I assign a ng-click="" directive on the element outside the directive. Do you have any idea why this is so, and is there a way to work around it?Lockwood
Hard to say without seeing code of what you are trying to do. Can you replicate it in Plunker?Paternal
Hey! It just started working! I don't know how but it works without the ng-click attribute. I must have changed something, I really don't know what. I only found out after I did a plunker mock up: plnkr.co/edit/2KRDp6gPcT5wtWe7eQJY?p=info Thanks much and sorry if I wasted your time.Lockwood

© 2022 - 2024 — McMap. All rights reserved.