I am currently encountering Durandal to Aurelia Conversion issues:
The way Aurelia handles computed properties, throttling and subscriptions is very different from the way knockout handled them and I am struggling to convert some code without having to do a large amount of refactoring.
Here is a snippet from Knockout’s Documentation Page that I am struggling to find a proper Aurelia solution for:
this.instantaneousValue = ko.observable();
this.throttledValue = ko.computed(this.instantaneousValue)
.extend({ throttle: 400 });
// Keep a log of the throttled values
this.loggedValues = ko.observableArray([]);
this.throttledValue.subscribe(function (val) {
if (val !== '')
this.loggedValues.push(val);
}, this);
I would expect to be able to write something like this in Aurelia:
//This was the pattern I assumed would work:
this.instantaneousValue = null;
// Keep a log of the throttled values
this.loggedValues = [];
this.bindingEngine
.expressionObserver(this, 'instantaneousValue & throttle:400')
.subscribe((newValue, oldValue) => {
if (newValue !== '') {
this.loggedValues.push(newValue);
this.throttledValue = newValue;
}
});
The above code did not work so I thought perhaps Aurelia Would Support this:
this.instantaneousValue = null;
// Keep a log of the throttled values
this.loggedValues = [];
this.bindingEngine
.propertyObserver(this, 'throttledValue')
.subscribe((newValue, oldValue) => {
if (newValue !== '')
this.loggedValues.push(newValue);
});
@computedFrom('instantaneousValue & throttle:400')
get throttledValue() {
return this.instantaneousValue;
}
But that did not work either.
It seems that there is no supported one-to-one solution. After debugging through the binding engine I discovered that this was possible but I had to write it like this:
this.instantaneousValue = null;
// Keep a log of the throttled values
this.loggedValues = [];
this.throttledValueBinding = this.bindingEngine
.createBindingExpression('throttledValue', 'throttledValue & debounce:1500', 2, this.resources.lookupFunctions)
.createBinding(this);
this.throttledValueBinding.bind(view); //assume this is in the created method
this.throttledValueObserver = subscriptionBinding.observerLocator.getObserver(this, 'throttledValue');
this.throttledValueSubscription = this.bindingEngine
.propertyObserver(this, 'instantaneousValue')
.subscribe((newValue, oldValue) => {
this.subscriptionObserver.callSubscribers(newValue, oldValue);
});
this.instantaneousValueSubscription = this.bindingEngine
.propertyObserver(this, 'instantaneousValue')
.subscribe((newValue, oldValue) => {
if (newValue !== '')
this.loggedValues.push(newValue);
});
I do not like this solution. It only works because this example does not require us to observe multiple values. Is there a better way of doing this?