-
Notifications
You must be signed in to change notification settings - Fork 31
/
angular-debounce.js
67 lines (66 loc) · 2.17 KB
/
angular-debounce.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'use strict';
angular.module('debounce', [])
.service('debounce', ['$timeout', function ($timeout) {
return function (func, wait, immediate, invokeApply) {
var timeout, args, context, result;
function debounce() {
/* jshint validthis:true */
context = this;
args = arguments;
var later = function () {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
}
};
var callNow = immediate && !timeout;
if (timeout) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait, invokeApply);
if (callNow) {
result = func.apply(context, args);
}
return result;
}
debounce.cancel = function () {
$timeout.cancel(timeout);
timeout = null;
};
return debounce;
};
}])
.directive('debounce', ['debounce', '$parse', function (debounce, $parse) {
return {
require: 'ngModel',
priority: 999,
link: function ($scope, $element, $attrs, ngModelController) {
var debounceDuration = $parse($attrs.debounce)($scope);
var immediate = !!$parse($attrs.immediate)($scope);
var debouncedValue, pass;
var prevRender = ngModelController.$render.bind(ngModelController);
var commitSoon = debounce(function (viewValue) {
pass = true;
ngModelController.$$lastCommittedViewValue = debouncedValue;
ngModelController.$setViewValue(viewValue);
pass = false;
}, parseInt(debounceDuration, 10), immediate);
ngModelController.$render = function () {
prevRender();
commitSoon.cancel();
//we must be first parser for this to work properly,
//so we have priority 999 so that we unshift into parsers last
debouncedValue = this.$viewValue;
};
ngModelController.$parsers.unshift(function (value) {
if (pass) {
debouncedValue = value;
return value;
} else {
commitSoon(ngModelController.$viewValue);
return debouncedValue;
}
});
}
};
}]);