Pete BD gave a good start to the debounce service, however, I see two problems:
- returns when you should send in a work() callback that uses javascript closure if you need to change state in the caller.
- timeout variable - isn't that timeout variable a problem? timeout[] maybe? imagine 2 directives using debounce - signalr, input form validator,
I believe the factory approach would break down.
What I am currently using:
I changed factory to a service so each directive gets a NEW instance of debounce aka new instance of the timeout variable. - i haven't ran into a situation where 1 directive will need timeout to be timeout[].
.service('reactService', ['$timeout', '$q', function ($timeout, $q) {
this.Debounce = function () {
var timeout;
this.Invoke = function (func, wait, immediate) {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
if (timeout) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
return this;
}
}]);
in my angularjs remote validator
.directive('remoteValidator', ['$http', 'reactService', function ($http, reactService) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
var newDebounce = new reactService.Debounce();
var work = function(){
//....
};
elm.on('blur keyup change', function () {
newDebounce.Invoke(function(){ scope.$apply(work); }, 1000, false);
});
}
};
}])