What I am trying to achieve is to get the changed event to fire only when the new value has changed. With the control below, the changed event fires twice - once with the current value and then a second time with the new value.
<template>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">${label}</span>
</div>
<div class="d-inline">
<select class="custom-select w-100" value.bind="value">
<option if.bind="showOption">[${label}]</option>
<option repeat.for="item of datasource" model.bind="item">${item.name}</option>
</select>
</div>
</div>
</template>
import { autoinject, bindable, bindingMode } from "aurelia-framework";
import {TaskQueue} from "aurelia-framework";
@autoinject
export class FormSelectControl {
@bindable public label = "Select";
@bindable({ defaultBindingMode: bindingMode.twoWay }) public value;
@bindable public datasource;
@bindable public showOption = false;
constructor(private readonly element: Element, private readonly taskQueue: TaskQueue) {
}
public valueChanged(newValue) {
const evt = new CustomEvent("change", {
bubbles: true,
detail: newValue
});
this.taskQueue.queueMicroTask(() => {
this.element.dispatchEvent(evt);
});
}
}
I’ve tried the obvious things such as
if(newValue !== oldValue) {
...
this.element.dispatchEvent(evt);
...
}
but the event never fires.
In the view
<form-select-control label="Select something" datasource.bind="myDataList" value.bind="selectedItem" change.delegate="onSelectedItemChanged($event)"></form-select-control>
and in the model
public onSelectControlChanged(){
this.loadDataFromServer(this.selectedItem.id);
// check selectedItem is the new data
}
It is here that I need to check that the selectedItem
has changed, otherwise it hits the server for the data is currently in the viewModel and then again for the new
value of the selectedItem.