UNPKG

2.31 kBPlain TextView Raw
1import {
2 bindingMode,
3 sourceContext,
4 targetContext,
5 bindingBehavior
6} from 'aurelia-binding';
7
8const unset = {};
9
10function debounceCallSource(event) {
11 const state = this.debounceState;
12 clearTimeout(state.timeoutId);
13 state.timeoutId = setTimeout(() => this.debouncedMethod(event), state.delay);
14}
15
16function debounceCall(context, newValue, oldValue) {
17 const state = this.debounceState;
18 clearTimeout(state.timeoutId);
19 if (context !== state.callContextToDebounce) {
20 state.oldValue = unset;
21 this.debouncedMethod(context, newValue, oldValue);
22 return;
23 }
24 if (state.oldValue === unset) {
25 state.oldValue = oldValue;
26 }
27 state.timeoutId = setTimeout(() => {
28 const _oldValue = state.oldValue;
29 state.oldValue = unset;
30 this.debouncedMethod(context, newValue, _oldValue);
31 }, state.delay);
32}
33
34@bindingBehavior('debounce')
35export class DebounceBindingBehavior {
36 bind(binding, source, delay = 200) {
37 const isCallSource = binding.callSource !== undefined;
38 const methodToDebounce = isCallSource ? 'callSource' : 'call';
39 const debouncer = isCallSource ? debounceCallSource : debounceCall;
40 const mode = binding.mode;
41 const callContextToDebounce = mode === bindingMode.twoWay || mode === bindingMode.fromView ? targetContext : sourceContext;
42
43 // stash the original method and it's name.
44 // note: a generic name like "originalMethod" is not used to avoid collisions
45 // with other binding behavior types.
46 binding.debouncedMethod = binding[methodToDebounce];
47 binding.debouncedMethod.originalName = methodToDebounce;
48
49 // replace the original method with the debouncing version.
50 binding[methodToDebounce] = debouncer;
51
52 // create the debounce state.
53 binding.debounceState = {
54 callContextToDebounce,
55 delay,
56 timeoutId: 0,
57 oldValue: unset
58 };
59 }
60
61 // eslint-disable-next-line @typescript-eslint/no-unused-vars
62 unbind(binding, source) {
63 // restore the state of the binding.
64 const methodToRestore = binding.debouncedMethod.originalName;
65 binding[methodToRestore] = binding.debouncedMethod;
66 binding.debouncedMethod = null;
67 clearTimeout(binding.debounceState.timeoutId);
68 binding.debounceState = null;
69 }
70}