Automatically pass $ event using ng-click?

I know that I can access the click event from ng-click if I pass the $event object as follows:

 <button ng-click="myFunction($event)">Give me the $event</button> function myFunction (event) { typeof event !== "undefined" // true } 

This is a little annoying to skip $event explicitly each time. Is it possible to set ng-click to somehow pass its functions to default?

+55
javascript angularjs javascript-events angularjs-directive angularjs-ng-click
Jan 13 '14 at 21:14
source share
4 answers

Take a look at the source of the ng-click directive:

 ... compile: function($element, attr) { var fn = $parse(attr[directiveName]); return function(scope, element, attr) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); }; } 

It shows how the event object is passed into the ng-click expression, using $event as the parameter name. This is done using the $ parse service, which does not allow the parameters to expire to the target area, which means the answer is no , you cannot access the $event object by any other but through the callback parameter.

+55
Jan 13 '14 at 21:27
source share

Add $ event to the ng-click, for example: <button type="button" ng-click="saveOffer($event)" accesskey="S"></button>

Then jQuery.Event was passed to the callback:

enter image description here

+25
Aug 05 '14 at 7:39
source share

As others have said, you cannot strictly do what you ask. However, all the tools available for the angular framework are really available to you! This means that you can write your own elements and provide this function yourself. I wrote one of them as an example, which you can see on the following plunkr ( http://plnkr.co/edit/Qrz9zFjc7Ud6KQoNMEI1 ).

The key parts of this is that I define a "clickable" element (don't do this if you need older IE support). In the code that looks like this:

 <clickable> <h1>Hello World!</h1> </clickable> 

Then I defined a directive to take this interactive element and turn it into what I want (something that automatically sets my click event):

 app.directive('clickable', function() { return { transclude: true, restrict: 'E', template: '<div ng-transclude ng-click="handleClick($event)"></div>' }; }); 

Finally, in my controller, I have a click event ready to go:

 $scope.handleClick = function($event) { var i = 0; }; 

Now it’s worth noting that this hardcodes the name of the method that handles the click event. If you want to eliminate this, you must provide the directive with the name of your click handler and "tada" - you have an element (or attribute) that you can use and should never enter "$ event" again.

Hope this helps!

+11
Jan 13 '14 at
source share

I would not recommend doing this, but you can override the ngClick directive to do what you are looking for. This does not mean what you need.

Given the initial implementation:

 compile: function($element, attr) { var fn = $parse(attr[directiveName]); return function(scope, element, attr) { element.on(lowercase(name), function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); }; } 



We can do this to override it:

 // Go into your config block and inject $provide. app.config(function ($provide) { // Decorate the ngClick directive. $provide.decorator('ngClickDirective', function ($delegate) { // Grab the actual directive from the returned $delegate array. var directive = $delegate[0]; // Stow away the original compile function of the ngClick directive. var origCompile = directive.compile; // Overwrite the original compile function. directive.compile = function (el, attrs) { // Apply the original compile function. origCompile.apply(this, arguments); // Return a new link function with our custom behaviour. return function (scope, el, attrs) { // Get the name of the passed in function. var fn = attrs.ngClick; el.on('click', function (event) { scope.$apply(function () { // If no property on scope matches the passed in fn, return. if (!scope[fn]) { return; } // Throw an error if we misused the new ngClick directive. if (typeof scope[fn] !== 'function') { throw new Error('Property ' + fn + ' is not a function on ' + scope); } // Call the passed in function with the event. scope[fn].call(null, event); }); }); }; }; return $delegate; }); }); 

You will then pass your functions as follows:

 <div ng-click="func"></div> 

Unlike:

 <div ng-click="func()"></div> 



jsBin : http://jsbin.com/piwafeke/3/edit

As I said, I would recommend not , but this is a proof of concept, showing you that yes - you can really overwrite / expand / increase the built-in angular behavior to suit your needs. Without having to dig it all in the original implementation.

Please use it with caution if you decide to go this route (this is a lot of fun).

+2
Jul 23 '14 at
source share



All Articles