-
-
Save bigopon/4fec87bd40bdfbd7ed10e7ad8f37fdd8 to your computer and use it in GitHub Desktop.
Aurelia Gist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="./debounce2"></require> | |
<require from='./throttle2'></require> | |
<style> | |
label { | |
display: block; | |
margin: 16px 0; | |
} | |
input { | |
display: block; | |
} | |
.demo { | |
padding: 5px 0; | |
} | |
</style> | |
<div class='demo'> | |
<h2>Debounce</h2> | |
<label> | |
two-way | |
<input value.two-way="twoWay & debounce2:1000"> | |
model: ${twoWay} | |
</label> | |
<label> | |
from-view | |
<input value.from-view="fromView & debounce2:1000"> | |
model: ${fromView} | |
</label> | |
<label> | |
to-view | |
<input disabled value.to-view="toView & debounce2:2000"> | |
model: ${toView} | |
</label> | |
<label> | |
trigger | |
<input ref="triggerInput" disabled input.trigger="trigger = trigger + 1 & debounce2:2000"> | |
model: ${trigger} | |
</label> | |
</div> | |
<div class='demo'> | |
<h2>Throttle</h2> | |
<label> | |
two-way | |
<input value.two-way="twoWay & throttle2:1000"> | |
model: ${twoWay} | |
</label> | |
<label> | |
from-view | |
<input value.from-view="fromView & throttle2:1000"> | |
model: ${fromView} | |
</label> | |
<label> | |
to-view | |
<input disabled value.to-view="toView & throttle2:1000"> | |
model: ${toView} | |
</label> | |
<label> | |
trigger | |
<input ref="triggerInput" disabled input.trigger="trigger = trigger + 1 & throttle2:1000"> | |
model: ${trigger} | |
</label> | |
</div> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class App { | |
twoWay = 'two-way'; | |
fromView = 'from-view'; | |
toView = 'to-view'; | |
trigger = 0; | |
constructor() { | |
const interval = setInterval(() => { | |
this.toView += 'x'; | |
this.triggerInput.dispatchEvent(new CustomEvent('input')); | |
}, 333); | |
setTimeout(() => clearInterval(interval), 3000); | |
} | |
attached() { | |
console.clear(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {bindingMode} from 'aurelia-binding'; | |
// todo: import from binding | |
const targetContext = 'Binding:target'; | |
const sourceContext = 'Binding:source'; | |
const {twoWay, fromView} = bindingMode; | |
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; | |
console.log('firing--', newValue, oldValue); | |
this.debouncedMethod(context, newValue, oldValue); | |
}, state.delay); | |
} | |
export class Debounce2BindingBehavior { | |
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 | |
}; | |
} | |
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Aurelia</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
</head> | |
<body aurelia-app> | |
<h1>Loading...</h1> | |
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script> | |
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script> | |
<script> | |
require(['aurelia-bootstrapper']); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
bindingMode, | |
sourceContext, | |
// targetContext | |
} from 'aurelia-binding'; | |
const targetContext = 'Binding:target'; | |
const unset = {}; | |
function throttleCallSource() { | |
} | |
function throttleCall(context, newValue, oldValue) { | |
let state = this.throttleState; | |
if (context !== state.contextToThrottle) { | |
this.throttledMethod(context, newValue, oldValue); | |
return; | |
} | |
let elapsed = +new Date() - state.last; | |
if (elapsed >= state.delay) { | |
clearTimeout(state.timeoutId); | |
state.timeoutId = null; | |
state.last = +new Date(); | |
this.throttledMethod(context, newValue, oldValue); | |
return; | |
} | |
state.oldValue = oldValue; | |
state.newValue = newValue; | |
if (state.timeoutId === null) { | |
state.timeoutId = setTimeout( | |
() => { | |
state.timeoutId = null; | |
state.last = +new Date(); | |
this.throttledMethod(context, state.newValue, state.oldValue); | |
}, | |
state.delay - elapsed | |
); | |
} | |
} | |
export class Throttle2BindingBehavior { | |
bind(binding, source, delay = 200) { | |
// determine which method to throttle. | |
// let methodToThrottle = 'updateTarget'; // one-way bindings or interpolation bindings | |
// if (binding.callSource) { | |
// methodToThrottle = 'callSource'; // listener and call bindings | |
// } else if (binding.updateSource && binding.mode === bindingMode.twoWay) { | |
// methodToThrottle = 'updateSource'; // two-way bindings | |
// } | |
const isCallSource = binding.callSource !== undefined; | |
const methodToThrottle = isCallSource ? 'callSource' : 'call'; | |
const debouncer = isCallSource ? throttleCallSource : throttleCall; | |
const mode = binding.mode; | |
const callContextToThrottle = 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.throttledMethod = binding[methodToThrottle]; | |
binding.throttledMethod.originalName = methodToThrottle; | |
// replace the original method with the throttling version. | |
binding[methodToThrottle] = throttleCall; | |
// create the throttle state. | |
binding.throttleState = { | |
contextToThrottle: callContextToThrottle, | |
delay: delay, | |
last: 0, | |
timeoutId: null, | |
oldValue: unset | |
}; | |
} | |
unbind(binding, source) { | |
// restore the state of the binding. | |
let methodToRestore = binding.throttledMethod.originalName; | |
binding[methodToRestore] = binding.throttledMethod; | |
binding.throttledMethod = null; | |
clearTimeout(binding.throttleState.timeoutId); | |
binding.throttleState = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment