ng-ampere-debounce seems to stop working in AngularJS 1.2
-
26-12-2019 - |
Pregunta
I've been using the jQuery / AngularJS Directive for debouncing inputs in a Firebase-backed app. It came from Lars Gersmann's post, and was working great:
http://orangevolt.blogspot.com.au/2013/08/debounced-throttled-model-updates-for.html
Updating from Angular 1.0.8 to 1.2 seems to break things. Each time the directive fires, instead of pulling the events from the element, the $._data function brings back an undefined, resulting in this error:
TypeError: Object.keys called on non-object at Function.keys (native)
It's defined here:
var map = $._data( element[0], 'events'),
events = $.each( Object.keys( map), function( index, eventName) {
// map is undefined :(
...
}
Did something change in AngularJS, or even jQuery, that wouldn't pull the events of this element like it used to?
(Side note, I'm using jQuery version 1.8.3, which hasn't changed in the Angular upgrade).
Thanks to anyone who can shed some light on this!
Solución
You can access those events instead by using unbinds, binds and the Angular $timeout
method to create a simpler debounce script. This is based off this post about blocking ngChange
events.
This is a rewritten debounce directive that seems to work in Angular 1.2. It unbinds the input then applies changes with $setViewValue
after a 1000ms delay. I've also added an instant change on blur. The key to making this work over the original post was setting priority.
angular.module('app', []).directive('ngDebounce', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
priority: 99,
link: function(scope, elm, attr, ngModelCtrl) {
if (attr.type === 'radio' || attr.type === 'checkbox') return;
elm.unbind('input');
var debounce;
elm.bind('input', function() {
$timeout.cancel(debounce);
debounce = $timeout( function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
}, 1000);
});
elm.bind('blur', function() {
scope.$apply(function() {
ngModelCtrl.$setViewValue(elm.val());
});
});
}
}
});
Plus JSFiddle Demo