cc @AshleyGrant
I have just read Ashely’s post.
I can do it in simpler alternative way, without deep understanding of aurelia-binding.
My approach is to use value converter, not binding behavior. The result is human understandable code, plus more permissive in chain of value converters.
Note: beware the fromView expects a simple propertyExpression like "address.city", otherwise the setExp will fail. But this doesn’t mean GetValueConverter cannot be used for complex expression like "address.state + ' ' + address.zip". You can still use GetValueConverter in one-way binding with complex expression, where fromView is never called.
Update: thx for @bigopon’s help, it now works correctly if used in more than 1 place.
@inject(Parser)
export class GetValueConverter {
constructor(parser) {
this.parser = parser;
}
toView(_: any, model: any, propertyExpression: string): any {
let getExp = this.parser.parse(propertyExpression);
return getExp.evaluate({ bindingContext: model });
}
fromView(value: any, model: any, propertyExpression: string): any {
let setExp = this.parser.parse(propertyExpression + ' = $value');
setExp.evaluate({
bindingContext: model,
overrideContext: { $value: value }
});
return model;
}
}
The downside is the binding is now verbose, you have to call model twice in order to pass enough information to the value converter.
<input value.bind="model | get:model:property.expression | localDebug">
See it working here: