I want to override directive ng-click: to some make some $rootscope changes before each execution of ng-click. How to do it?
2 Answers
Every directive is a special service inside AngularJS, you can override or modify any service in AngularJS, including directive
For example remove built-in ngClick
angular.module('yourmodule',[]).config(function($provide){
$provide.decorator('ngClickDirective', ['$delegate', function($delegate) {
//$delegate is array of all ng-click directive
//in this case first one is angular buildin ng-click
//so we remove it.
$delegate.shift();
return $delegate;
}]);
});
angular support multiple directives to the same name so you can register you own ngClick
Directive
angular.module('yourmodule',[]).directive('ngClick',function (){
return {
restrict : 'A',
replace : false,
link : function(scope,el,attrs){
el.bind('click',function(e){
alert('do you feeling lucky');
});
}
}
});
check out http://plnkr.co/edit/U2nlcA?p=preview
I wrote a sample that removed angular built-in ng-click
and add a customized ngClick

- 35,625
- 19
- 175
- 265

- 3,708
- 2
- 18
- 15
-
This was immensely helpful to me! Thanks. – Jonathan Palumbo Jan 10 '15 at 00:28
-
2How would you keep both delegates but let the first handler conditionally propagate to the built-in delegate? – Alex White Sep 03 '15 at 21:01
-
@AlexWhite my guess is that it's impossible since the `click` binding is being done with `element.bind` inside another function callback already: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngEventDirs.js#L62 – saiyancoder Oct 04 '15 at 02:35
-
@AlexWhite the simple solution is to simulate this behavior by making a copy of the ngClick event handler and $parse usage in your directive and calling it conditionally from your event handler. – meticoeus Oct 22 '15 at 03:31
You can't override AngularJS built-in directives. However, you can define multiple directives with the same name and have them executed against the same element. By assigning appropriate priority
to your directive, you can then control whether your directive runs before or after a built-in directive.
This plunker shows how to build an ng-click
directive that executes before the built-in ng-click
does. The code is also shown below. When clicking the link, the custom ng-click
will run first, then the built-in ng-click
does.
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="jquery@1.9.0" data-semver="1.9.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.js"></script>
<script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<a ng-click="alert()">Click me</a>
</body>
</html>
script.js
angular.module('app', [])
.directive('ngClick', function($rootScope) {
return {
restrict: 'A',
priority: 100, // give it higher priority than built-in ng-click
link: function(scope, element, attr) {
element.bind('click', function() {
// do something with $rootScope here, as your question asks for that
alert('overridden');
})
}
}
})
.controller('MyCtrl', function($scope) {
$scope.alert = function() {
alert('built-in!')
}
})

- 49,745
- 5
- 67
- 85
-
Buu, can we stop first ng-click totally? i mean after running 'overridden' alert, 'built-in' not to run. – Morteza Oct 21 '13 at 07:18
-
Don't pass an expression to ng-click, see http://plnkr.co/edit/uROkIcGKLspLnVsjmAKn?p=preview. If you have to pass s/t, then don't handle it, e.g. $scope.alert = function() {}. – Buu Oct 21 '13 at 19:26
-
1
-
3Concur with JackNova, this answer is not correct. * you CAN override/replace all directives as @eric-chen shows below * this example approach will run into issues - you cannot have multiple directives on the same element requesting an isolate scope or setting a template. Eric's approach solves that too – mr_than Jun 10 '15 at 21:46