Reputation: 785
So usually, when I want to subscribe to a variable, I would just declare the variable and declare a function with the variable name followed by the word 'Changed' at the end of the function such as below:
test = '';
testChanged() {
// do stuff here
}
Aurelia provides a very nice way of handling this. However, what do I do if I want to subscribe to a property that is inside an object without using the bindingEngine.propertyObserver
For example:
model = {
a: '',
b: ''
}
How do I subscribe to model.a
using the same convention as above?
Upvotes: 1
Views: 1131
Reputation: 6632
You will want to use the Object.defineProperty method to watch an objects specific properties for changes. I believe this is how the Aurelia @bindable
and @observable
methods work behind the scenes in most cases.
Object.defineProperty(this.model, 'a', {
configurable: true,
enumerable: true,
get: () => {
return this.model.__a;
},
set: (v) => {
this.model.__a = v;
this.modelChanged(v);
}
});
First thing worth mentioning is inside of the setter method set
you can't set the original value, otherwise it will trigger a recursive loop and throw a stack error, so you assign the value to a double underscore prefixed name, akin to a temporary hidden variable.
Then define our callback function inside of our class:
modelChanged(value) {
console.log(value);
}
Lastly, tie it all together and use a setTimeout to test:
export class MyViewModel {
model = {
a: '',
b: ''
};
constructor() {
Object.defineProperty(this.model, 'a', {
configurable: true,
enumerable: true,
get: () => {
return this.model.__a;
},
set: (v) => {
this.model.__a = v;
this.modelChanged(v);
}
});
setTimeout(() => {
this.model.a = 'HELLO!';
}, 3000);
}
modelChanged(value) {
console.log(value); // After 3 seconds, this should be "HELLO!" in the browser console.
}
}
Having said all of this, worthy of note is the bindingEngine.propertyObserver
functionality essentially does the same thing under hood. I would honestly consider just using propertyObserver
instead of introducing a heap of lines of code into your app to watch a property.
Upvotes: 3