Reputation: 82341
my-view-model.html
<input on-scan.bind="onAirbillScanned" value.bind="airbill"/>
on-scan.ts
attached() {
var scannerOptions = { onComplete: this.onScan.bind(this), preventDefault: true };
(<any>$(this.element)).scannerDetection(scannerOptions);
-- Code to add a signal to the value binding.
}
onScan(scannedValue, data) {
if (typeof (this.value) == 'function') {
let updatedScanValue = this.value(scannedValue);
if (updatedScanValue !== undefined)
this.element.value = updatedScanValue;
else
this.element.value = scannedValue;
-- Code to Call the Signal
}
}
I have a custom attribute that allows me to detect a scan, modify the scanned-in data and set it to be the value of the input element.
However, I need to update aurelia with the updated value.
I can just fire off an 'input' event to make this happen. But I have found side effects when random 'input' events are fired.
I would rather use the signal system outlined here: http://aurelia.io/docs.html#/aurelia/binding/1.0.0-beta.1.1.3/doc/article/binding-binding-behaviors
But the problem is that I need the signal to be on the value.bind
binding.
Is there a way (using my access to the element
that the binding is on) to update the value.binding
to have a signal that I can call to get the binding to update?
Basically I am looking for something like this:
addSignal(element, property, signal) {...}
..
addSignal(this.element, 'value', 'scanFinished');
And it will update the input's value binding to look like this:
<input on-scan.bind="onAirbillScanned" value.bind="airbill & signal: 'scanFinished'"/>
But more than just re-writing the html, it would have to update Aurelia to know about the signal.
Or is there a signal value that Aurelia adds to all bindings for scenarios like this?
NOTE: It would be awesome if all aurelia bindings had a AureliaBinding
signal defined so you could target that control and send an event that will have no side effects other than to update the binding.
Upvotes: 2
Views: 1001
Reputation: 26406
I think you're having trouble because you're at the tipping point where it's time to switch from a custom attribute to an approach that uses a custom element.
You can circumvent the whole issue by doing something like this:
scanner.html
<template>
<input ref="input" value.bind="value">
</template>
scanner.js
import {bindingMode} from 'aurelia-framework';
export class Scanner {
@bindable({ defaultBindingMode: bindingMode.twoWay }) value;
@bindable scanModifier = x => x;
input: HTMLInputElement;
attached() {
let scannerOptions = {
onComplete: value => this.value = this.scanModifier(value),
preventDefault: true
};
(<any>$(this.input)).scannerDetection(scannerOptions);
}
detached() {
(<any>$(this.input)).scannerDetection('destroy');
}
}
usage:
<require from="./scanner"></require>
<scanner value.bind="airbill" scan-modifier.call="onAirbillScanned($event)"></scanner>
This could still be done with a custom attribute but it seems more natural to me this way. What do you think?
Upvotes: 2