I wouldn't recommend doing this, but you can override the ngClick
directive to do what you are looking for. That's not saying, you should.
With the original implementation in mind:
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;
});
});
Then you'd pass in your functions like this:
<div ng-click="func"></div>
as opposed to:
<div ng-click="func()"></div>
jsBin: http://jsbin.com/piwafeke/3/edit
Like I said, I would not recommend doing this but it's a proof of concept showing you that, yes - you can in fact overwrite/extend/augment the builtin angular behaviour to fit your needs. Without having to dig all that deep into the original implementation.
Do please use it with care, if you were to decide on going down this path (it's a lot of fun though).
undefined
should be"undefined"
, otherwise the expression will always evaluate to false astypeof
returns a string. – Laughable$event
anyway. – PigeonwingmyFunction
is part of a controller. A controller shouldn't care about the UI. Furthermore a simple button has no default action. And angular does prevent many default actions anyway. So while you're right, of course, it's hard to imagine a good use case. – PigeonwingcontextMenu
which provides several functions for the scope (open, close, toggle), which are called with the name of a specificcontextMenu
, egng-click="account_menu.toggle()"
. The menu itself is in a different element, eg<div context-menu="account_menu"></div>"
. In order to position the menu correctly on the page right below the trigger element that calledtoggle()
, I want access tong-click
's$event.target
element, so that I can get its coordinates. Do let me know if there is a simpler way :) – GoldeyecontextMenu
should be self-containing. – PigeonwingcontextMenu
is a self-containing directive whose functionsopen
,close
, andtoggle
are the ones which want access to$event
.ng-click
is simply used to trigger those functions (in thecontextMenu
directive). The point is that I should be able to use whichever ofng-click
,ng-mouseover
, etc, to handle differentcontextMenu
s differently. If you're interested, here is a highly simplified example jsfiddle.net/uYayL/1. – GoldeyecontextMenu
to encapsulate the behaviour of the actual menu, and not an arbitrary element triggering actions on it. I mean, the button is not the menu :) either way, UI manipulation is captured within a single directive. – Goldeyetitle
attribute. Which in turn triggers a popup on hover. That's the same concept. And no: in your case theng-click
does the UI manipulation. That fact that it calls a method defined somewhere else doesn't change that. – Pigeonwingtitle
attribute argument is very convincing.. So how would you handle a situation where different buttons need to trigger the context menu in different ways (eg one with hover, one with click), while the menu itself looks and behaves exactly the same? – Goldeye