UPDATE: It looks like this is a known bug: https://github.com/aurelia/templating/issues/253
I am leaving it here for reference / searchability purposes.
The Code:
input-mask.ts (Full code can be seen here)
@customAttribute('input-mask')
@inject(Element)
export class InputMaskCustomAttribute {
@bindable({ defaultBindingMode: bindingMode.twoWay,
changeHandler: 'onUnmaskedValueChanged' })
unmaskedValue: any;
onUnmaskedValueChanged(newValue, oldValue) {
console.log('unmaskedValue updated from inside the custom attribute');
}
@bindable
mask: string;
attached() {
this.eventTarget.on('focusout', (e: any) => {
this.unmaskedValue = (<any>$(this.element)).cleanVal()
this.fireEvent(e.target, 'input');
});
}
// Code for constructor, fireEvent and to setup the mask...
}
carrier.html
<input input-mask="mask.bind: carrier.airbillMask; unmasked-value.bind: airbill"
value.bind="formattedAirbill"/>
UPDATE: To work around this bug, change to
unmasked-value.two-way
and the binding will work.
carrier.ts
@bindable({ defaultBindingMode: bindingMode.twoWay})
carrier: EntityInterfaces.ICarrier;
@bindable({ defaultBindingMode: bindingMode.twoWay })
formattedAirbill: string;
@bindable({ defaultBindingMode: bindingMode.twoWay, changeHandler: 'onAirbillChanged' })
airbill: string;
onAirbillChanged() {
console.log('Airbill was set!');
}
The Problem:
The data seems to flow into the @bindable
variable just fine. As the mask changes, the value in the custom attribute is changed.
But it does not seem to flow out if changes are made inside the custom-attribute.
Example Scenario:
After I edit the value in the input box, and exit the input, the focusout
event fires and the console statement that indicates that the unmasked Value was updated from inside the custom attribute prints:
unmaskedValue updated from inside the custom attribute
But (when the input looses focus) the console statement saying that the airbill
on the carrier.ts file was updated does not fire when I exit the input box:
This does not fire:
console.log('Airbill was set!');
This seems to show to me that the binding is not really two-way.
The Question:
How can I make this binding two-way? So that when I update unmaskedValue
inside the custom-attribute it will update the bound value in the view model?
Note: As a workaround, I was able change unmasked-value.bind
to be a method call (on-unmasked-value-changed.call="onUnmaskedValueChanged($event)
) and update the value in that method. So I don't NEED this to work. But I would like to know if it is possible for future use.
.two-way
(instead of just.bind
) in the HTML works around this issue. – Ariel