I was wondering, if it is possible, to extend Angular's input directive? I want to attach some listeners to all input fields on a page. I think you can decorate existing modules with $provide.decorate
, but I have no idea how to do this with a directive (and more precisely the input directive).
So, can anyone push me in the right direction? Some examples?
EDIT
Here is my directive that I have so far:
angular.module('onFocusBlur').
directive('onFocusBlur', ["$rootScope", function($rootScope) {
return {
restrict: "A",
link: function(scope, elem, attrs) {
elem.bind('focus',function() {
scope.$apply(function() {
$rootScope[attrs.onFocusBlur] = true;
});
});
elem.bind('blur',function() {
scope.$apply(function() {
$rootScope[attrs.onFocusBlur] = false;
});
});
}
};
}]);
In my view, I can add this to an input field like this:
<input type="email" ng-model="email" on-focus-blur="repositionNavBar">
The downside is, that for every input field, I have to attach this listener manually in my code. Therefore, it would be useful, to alter the existing input directive, to include this listeners.
Here's a short gist of how you could decorate the built in Angular input
directive, with $provide.decorator
as you yourself suggested.
app.config(function ($provide) {
// Suffix is "Directive" for decorating directives.
// $delegate refers to the original directive definition.
$provide.decorator('inputDirective', function ($delegate) {
// When decorating a directive, $delegate is an array containing
// all of the directives of the same name.
// We're interested in the first in this case.
var directive = $delegate[0];
// Store a reference to the original directive linking function.
var link = directive.link;
// Hook into the compile phase of the directive.
directive.compile = function () {
// The function returned by compile is your new link function.
// Or 'postLink', to be exact.
return function (scope, el, attrs) {
// Run the original link function.
link.apply(this, arguments);
// Your new listener function
function listener (e) {
console.log(e);
}
// Set up your listener(s).
el.bind('blur', listener);
el.bind('focus', listener);
};
};
// Return the decorated original ($delegate).
return $delegate;
});
});
Benefits of this approach, as I see it:
Here's a jsBin: http://jsbin.com/yafecinu/2/edit
I'd recommend you take a look at this article, that goes in-depth on decorating directives. The article covers extending not just linking phases, but controllers and pre-linking DOM manipulation aswell. A very good read!
See answer to this question. They talk about a couple different options to extend a directive from using $provide to making a directive with the same name.
Also, this link explains a few techniques (under "Extending Directives"): https://github.com/angular/angular.js/wiki/Understanding-Directives
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With