Tip: directives with the same name
August 28, 2013 tip directives
Since this blog is a blog for tips, let’s begin with the first one.
You want to log the clicks on a ng-click
directive. What could you do?
We can take this first approach:
File: index.html
<button ng-click="dummyClickFoo()" log>Submit</button>
<button ng-click="dummyClickBar()" log>Cancel</button>
File: log.js
app.directive('log', function($log) {
return {
link: function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
$log.log("ng-click clicked");
});
});
}
};
});
Try it
JS Bin
NOTE: Check the logging on your browser’s dev tools console.
That works. We log the clicks into the directive. That is good. But what if we have 200 ng-click
and we want to log them all? Putting the directive 200 times would work, but it is a lot of work.
Alright, let’s take a different approach. We are going to replicate the ng-click
to do the logging.
File: index.html
<button logging-click="dummyClickFoo()">Submit</button>
<button logging-click="dummyClickBar()">Cancel</button>
File: loggingClick.js
app.directive('loggingClick', function($parse, $log) {
return function(scope, element, attrs) {
var fn = $parse(attrs['loggingClick']);
element.bind('click', function(event) {
scope.$apply(function() {
$log.log("logging-click clicked");
fn(scope, {$event: event});
});
});
};
});
Try it
JS Bin
NOTE: Check the logging on your browser’s dev tools console.
This is the “original” (almost :P) ng-click
directive with logging. Works like the original but it also logs what we want.
What’s the problem? We need to use this directive instead of ng-click
and we could forget to use our logging version in one place and so we lose some of the logging.
What can we do? Easy, we can create a directive called ng-click
. Uh, won’t that replace the original one? No, Angular will run both. Uhm, it sounds good, let’s try:
File: index.html
<button ng-click="dummyClickFoo()">Submit</button>
<button ng-click="dummyClickBar()">Cancel</button>
File: ngClick.js
app.directive('ngClick', function($parse, $log) {
return function(scope, element, attrs) {
element.bind('click', function() {
scope.$apply(function() {
$log.log("logging-click clicked");
});
});
};
});
Try it
JS Bin
NOTE: Check the logging on your browser’s dev tools console.
We created a directive with the same name, which will log when we click.
Conclusion
By doing this we can write directives that we need to run when other directive appears. So if we need to do something in every <input>
we only need to write another input
directive… etc.