Mike
Mike

Reputation: 799

pass event to triggerHandler in angular

I want the same menu to appear when clicking on multiple different buttons.

How can I pass the original click event to the new created triggered event?

This is what I do today:

this.openMenuFromOther = function(event) {
  $timeout(function() {
    var ele = document.getElementById('userMenu');
    angular.element(ele).triggerHandler('click');
  }, 0);
}

In the demo you can see it creates a new event which doesn't correspond with the original click event and the menu opens on the main button and not on the clicked button.

CODEPEN DEMO

Upvotes: 1

Views: 941

Answers (2)

arc
arc

Reputation: 4691

The simple answer is: you can't.

Angular has no intent of giving you the option to reuse it. You can see this is their source code. $scope.$mdMenu = {} returns a different scope and therefore prevents you from changing any variable. Even "hacky" ways are really hard to find.

You would have to change menuContainer and triggerElement to your new trigger and then at the end change it back. But as mentioned, it would be really ugly to do so.


The cleanest solution is to make a template.

The template contains the menu you want to reuse. (this should be inside the <body ng-app="MyApp">)

<script type="text/ng-template" id="menu">
   <md-menu md-offset="0 60">
      ...
   </md-menu>
</script>

You then make a directive, e.g.

.directive('mdMenuButton', function($compile, $templateCache) {
  return {
    restrict: 'M',
    replace: 'true',
    template: $templateCache.get('menu')
    // as of now "templateUrl" doesn't work in this case
  }
})

You are now able to reuse this code as many times as you want like this

<!--directive: md-menu-button -->
<br/> different stuff not related
<br/> different stuff not related

<!--directive: md-menu-button -->
<br/> different stuff not related

Upvotes: 2

Hai.Xu
Hai.Xu

Reputation: 50

Please forgive me for my poor English

I try it. if you set params at triggerHandler function,then cannot get params at directive ng-click! The context is not an initial context in an angular event directive,the context is scope object,and extend a object {$event:event},where event is a current click event!

here is source snippet code:

element.on(eventName, function (event) {
    var callback = function () {
      fn(scope, {$event: event});
    };
    if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
      scope.$evalAsync(callback);
    } else {
      scope.$apply(callback);
    }
});

I think these way can do it:

  1. first way;

this.openMenuFromOther = function(event) {
      $scope.$menuEvent=event;
      $timeout(function() {
        var ele = document.getElementById('userMenu');
        angular.element(ele).triggerHandler('click');
      }, 0);
    }

use it like this:

  <md-button id="userMenu" aria-label="Open phone interactions menu" 
ng-click="ctrl.openMenu($mdMenu, $menuEvent)">
        Click here to open menu
</md-button>

  1. you can save event data on controller or element or other global object.

Upvotes: -1

Related Questions