Two-Way binding in an Aurelia Custom Attribute
Asked Answered
A

2

9

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.

Ariel answered 26/2, 2016 at 17:40 Comment(3)
Looks like this is a known bug: github.com/aurelia/templating/issues/253Ariel
Changing the binding to .two-way (instead of just .bind) in the HTML works around this issue.Ariel
Looks like this issue was closed, can you use it the way you wanted to now, without the workaround?Silin
U
0

This known bug have been fixed and closed on Mar 15, 2016 https://github.com/aurelia/templating/issues/253#issuecomment-189394955

Ulmaceous answered 7/3, 2018 at 13:21 Comment(0)
P
-1

Try to initialize the variable unmaskedValue with default value. Try null, undefined, '' and so on. I have done this before but I don`t remember in which version (certainly it was beta)

Porter answered 10/8, 2016 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.