aurelia-templating-resources
Version:
A standard set of behaviors, converters and other resources for use with the Aurelia templating library.
71 lines (62 loc) • 2.31 kB
text/typescript
import {
bindingMode,
sourceContext,
targetContext,
bindingBehavior
} from 'aurelia-binding';
const unset = {};
function debounceCallSource(event) {
const state = this.debounceState;
clearTimeout(state.timeoutId);
state.timeoutId = setTimeout(() => this.debouncedMethod(event), state.delay);
}
function debounceCall(context, newValue, oldValue) {
const state = this.debounceState;
clearTimeout(state.timeoutId);
if (context !== state.callContextToDebounce) {
state.oldValue = unset;
this.debouncedMethod(context, newValue, oldValue);
return;
}
if (state.oldValue === unset) {
state.oldValue = oldValue;
}
state.timeoutId = setTimeout(() => {
const _oldValue = state.oldValue;
state.oldValue = unset;
this.debouncedMethod(context, newValue, _oldValue);
}, state.delay);
}
@bindingBehavior('debounce')
export class DebounceBindingBehavior {
bind(binding, source, delay = 200) {
const isCallSource = binding.callSource !== undefined;
const methodToDebounce = isCallSource ? 'callSource' : 'call';
const debouncer = isCallSource ? debounceCallSource : debounceCall;
const mode = binding.mode;
const callContextToDebounce = mode === bindingMode.twoWay || mode === bindingMode.fromView ? targetContext : sourceContext;
// stash the original method and it's name.
// note: a generic name like "originalMethod" is not used to avoid collisions
// with other binding behavior types.
binding.debouncedMethod = binding[methodToDebounce];
binding.debouncedMethod.originalName = methodToDebounce;
// replace the original method with the debouncing version.
binding[methodToDebounce] = debouncer;
// create the debounce state.
binding.debounceState = {
callContextToDebounce,
delay,
timeoutId: 0,
oldValue: unset
};
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
unbind(binding, source) {
// restore the state of the binding.
const methodToRestore = binding.debouncedMethod.originalName;
binding[methodToRestore] = binding.debouncedMethod;
binding.debouncedMethod = null;
clearTimeout(binding.debounceState.timeoutId);
binding.debounceState = null;
}
}