1 | import {
|
2 | bindingMode,
|
3 | sourceContext,
|
4 | targetContext,
|
5 | bindingBehavior
|
6 | } from 'aurelia-binding';
|
7 |
|
8 | const unset = {};
|
9 |
|
10 | function debounceCallSource(event) {
|
11 | const state = this.debounceState;
|
12 | clearTimeout(state.timeoutId);
|
13 | state.timeoutId = setTimeout(() => this.debouncedMethod(event), state.delay);
|
14 | }
|
15 |
|
16 | function 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')
|
35 | export 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 |
|
44 |
|
45 |
|
46 | binding.debouncedMethod = binding[methodToDebounce];
|
47 | binding.debouncedMethod.originalName = methodToDebounce;
|
48 |
|
49 |
|
50 | binding[methodToDebounce] = debouncer;
|
51 |
|
52 |
|
53 | binding.debounceState = {
|
54 | callContextToDebounce,
|
55 | delay,
|
56 | timeoutId: 0,
|
57 | oldValue: unset
|
58 | };
|
59 | }
|
60 |
|
61 |
|
62 | unbind(binding, source) {
|
63 |
|
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 | }
|