-
-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Input bindings don't update when changes are reverted within a setter or changeHandler #442
Comments
I implemented a work around by using a binding signaler on the input - I don't consider this an acceptable 'fix' however but I'm posting in case someone comes across the same issue. Below is code for the numeric limit input. I only signal when the value has been clamped back to the same old value ( <input value.bind="limitConfig.limit & signal:limitConfig.limitSignal & updateTrigger:'blur'"> limitChanged(limit, oldLimit) {
if (typeof limit !== 'number') {
limit = Number(limit);
this.limit = limit;
}
let clamped = false;
if (this.enabled) {
if (this.lowerLimitConfig !== null && this.lowerLimitConfig.upperBound > limit) {
limit = this.lowerLimitConfig.upperBound;
clamped = true;
}
if (this.upperLimitConfig !== null && this.upperLimitConfig.lowerBound < limit) {
limit = this.upperLimitConfig.lowerBound;
clamped = true;
}
}
if (clamped) {
this.limit = limit;
}
if (clamped && limit === oldLimit) {
this.bindingSignaler.signal(this.limitSignal);
}
} |
A beforeUpdate(newValue,oldValue, cancel) would be nice here It turns out that with Aurelia you can easely generate demo apps and prototypes. But when it comes down to some very usual use cases like converting values (http://stackoverflow.com/questions/37882659/force-view-to-be-updated-from-within-a-valueconverter), or rejecting changes like mentioned here we often need to take a deep plunge and use much more advanced concepts, possibly scaring away people from using this nice framework after they have mastered the demo apps and tutorial phase. So what can we imo do. |
Thanks for the link to that issue @fopsdev - those advanced techniques are quite well... advanced! I agree this should be a little easier to accomplish as a standard operation that aurelia directly supports. I think to fix this issue in particular it needn't be something the developer has to handle themselves. I expect the input (value) binding should recheck the value after setting it and then reset the input/checked value appropriately. |
I'm with @AdamWillden on this. I was quite surprised to find that value converters don't support this behavior out of the box. It's a common use case to do some normalisation like <input value.bind="myProp | trim & validate" /> If I use something like the above now, the normalised value is passed to the model and used for validation - which is exactly what we want. However, some changes applied by For example: if I type some spaces in the input with the Right now if I want to normalise and keep my screen and model value in sync, my options are to
These solutions are all doable, but IMO overkill for what should be a simple and common use case. |
For now I've built this TypeScript base class for binding behaviors that do normalisation. Maybe it will be of use to others. export abstract class NormalisationBindingBehavior {
protected abstract normalise(value: any): any;
private get scopeName() {
return this.constructor.name;
}
bind(binding: any) {
const normalise = this.normalise.bind(this);
const updateSource = binding.updateSource.bind(binding);
binding[`${this.scopeName}UpdateSourceOriginal`] = binding.updateSource;
binding.updateSource = function(value: any) {
const normal = normalise(value);
updateSource(normal);
if (normal !== value) {
this.updateTarget(normal);
}
};
}
unbind(binding: any) {
binding.updateSource = binding[`${this.scopeName}UpdateSourceOriginal`];
delete binding[`${this.scopeName}UpdateSourceOriginal`];
}
} Example use: import {NormalisationBindingBehavior} from "./normalisation-binding-behavior";
export class TrimBindingBehavior extends NormalisationBindingBehavior {
protected normalise(value: string) {
return value.trim();
}
} <template>
<require from="bindingbehaviors/trim"></require>
<input value.bind="myVal & updateTrigger:'blur' & trim"/>
</template> (Note that I add EDIT: this doesn't play nicely with the |
I think these examples will show the issue clearly enough to void more explanation. The interpolated text shows the real value but the inputs don't revert to the underlying value.
getter/setter example: https://gist.run/?id=8c56fe352fd849462d39311ede2c8b5d
computed getter/setter example: https://gist.run/?id=14ce505a70736ca3c76943ac762fe836
changeHandler example: https://gist.run/?id=45e93cac4e74d8ffb702325d56a7192a
I believe the same can be said for textboxes too. I have alarm limits whose ranges are validated (which is related to this). If the limit is at 100, it cannot exceed 100 and 101 is entered it is reverted to a value of 100 but the input itself doesn't reflect this change.
Any ideas? Is this something that can be fixed in the binding system?
The text was updated successfully, but these errors were encountered: