@inlineView(`<template>
<input value.bind="firstName">
</template>`)
class Example {
@bindingProxy firstName(bindingValueSetter) {
// function run when the binding is bound, returns an object:
return {
// function run when the value of the binding is changed from the View:
next: (value) => bindingValueSetter(value),
// function run when the binding is unbind:
dispose: () => { }
}
}
}
This would solve the other uses of binding functions. Much cleaner than a getter with a getObserver
method and setter.
then we could do things like:
@inlineView(`<template>
${timer}
</template>`)
class Example {
@bindingProxy timer(bindingValueSetter) {
let i = 0;
let timer = setInterval(() => bindingValueSetter(i++), 1000);
return {
dispose: () => clearInterval(timer)
}
}
}
A self-contained one-way, stateless timer binding. 😄
Binding Proxies like that would really help implement alternative state management systems for Aurelia, like Redux or Cycle.js.
Then there could be a variation of a Binding Proxy, a Dynamic Binding Proxy:
@inlineView(`<template>
<input value.bind="firstName">
</template>`)
class Example {
@dynamicBindingProxy((promise, bindingValueSetter) => {
promise.then(promise => bindingValueSetter(value));
})
firstName = Promise.resolve('Jeremy');
}
or with Observables:
@dynamicBindingProxy((observable, bindingValueSetter) => {
let observer = observable.subscribe((next) => bindingValueSetter(next));
return {
dispose: () => observer.unsubscribe()
}
})
observable = Rx.Observable.interval(1000);
Really easy to make an abstraction then for the common things like Promises or Observables:
function promiseHandler(promise, bindingValueSetter) {
promise.then(value => bindingValueSetter(value));
}
function observableHandler(observable, bindingValueSetter) {
let observer = observable.subscribe((next) => bindingValueSetter(next));
return {
dispose: () => observer.unsubscribe()
}
}
function subjectHandler(rxSubject, bindingValueSetter) {
// sending values both to and from an Observable (an Rx Subject)
let observer = rxSubject.subscribe((next) => bindingValueSetter(next));
return {
next: value => rxSubject.next(value),
dispose: () => observer.unsubscribe()
}
}
class Example {
@dynamicBindingProxy(promiseHandler) firstName = Promise.resolve('Jeremy');
@dynamicBindingProxy(observableHandler) seconds = Rx.Observable.interval(1000);
}
Actually, a better name could be a "Binding Intercept" since we're intercepting the binding here.