I could set up the property observation in a view model, such as regions-list.js above, but it seems that it this should be the responsibility of the underlying model object.
It seems to me that you want some observable properties. If thatâs all what you need, then you can simply use the @observable decorator on your property. That should work, irrespective of whether your class is a view model, or not. And you donât have to bother about the BindingEngine. That is useful where you donât have access to source code of the class where you want to observe property, or donât want to put Aurelia dependency for whatever reason.
Thanks for your help.
So, the @observable is just for observing changing properties of a class?
My class has a property called data which is a Map where the values are regular JS objects (created when I dynamically load some JSON data). I want to observe the âshowâ property of every object in this Map. The UI is a bit like a hierarchy browser - loading âfoldersâ then listening for each one to be expanded -> then loading child objects.
Currently Iâm setting this up using the bindingEngine like this in the model view:
// for each object in the Map, observe the 'show' property.
this.regions_info.data.forEach((roi, roi_id) => {
this.observers.push(this.bindingEngine.propertyObserver(roi, 'show').subscribe(
(newValue, oldValue) => {
this.handleRoiShow(newValue, oldValue, roi_id);
}));
});
Using the subscribe() closure allows me to pass an additional roi_id parameter to the handler.
This is working but I would prefer it if the regions_info class itself was able to setup these observers.
class Region {
@observable public show: boolean = false;
public deleted: number = 0,
public constructor(
public name: string,
public shapes: Shapes, // assuming the Shapes type exists
){}
private showChanged(){
// handle the change event here;
// or publish the `{name}:show:changed` event from here to notify the actual handler(s).
}
}
Then you can use the following to set values in the map.
this.data.set(roiId, new Region(name, shapes));
I have used TS syntax, but I think you can transfer that to JS as well. Does this approach help you?