Reputation: 4295
I am writing a custom attribute in aurelia and in my attribute class, I have a bindable property named 'visibility'. Then binding to this property from outside (parent component) and changing the value on that component, fires visibilityChanged
but in my attribute class, when I change the value, the visibilityChanged
method does not get called.
For example:
export class PaOnScreenKeyboardCustomAttribute {
@bindable visibility = false;
visibilityChanged(newValue, oldValue) {
console.log('change visibility');
if (this.keyboardElement) {
this.keyboardElement.style.display = newValue ? 'initial' : 'none';
}
}
_onElementFocused(event) {
// let htmlElement = this; // use this if needed
this.visibility = true;
console.log('show');
}
_onElementDefocused(event) {
// let htmlElement = this; // use this if needed
this.visibility = false;
console.log('hide');
}
}
How should I change the property value inside the class, so that changing calls visibilityChanged
?
Upvotes: 1
Views: 436
Reputation: 4295
I found the answer and writing it down here. The problem was about the context being changed, and not about the propagation of change event.
I have set _onElementFocused
as listener over element focus event and I was passing the function and not using arrow functions or something else. See this:
showOnFocusChanged(newValue, oldValue) {
if (newValue === true || newValue === 'true') {
this.element.addEventListener('focus', this._onElementFocused);
this.element.addEventListener('focusout', this._onElementDefocused);
} else {
this.element.removeEventListener('focus', this._onElementFocused);
this.element.removeEventListener('focusout', this._onElementDefocused);
}
}
this way, in the _onElementFocused
function, the this refers to element that is calling the event. So this.visibility = true;
changes the visibility
property on that element and not on the viewmodel (custom attribute class). So I have changed it call to arrow function type and now everything goes right. Like this:
showOnFocusChanged(newValue, oldValue) {
if (newValue === true || newValue === 'true') {
this.element.addEventListener('focus', (event) => this._onElementFocused(event));
this.element.addEventListener('focusout', (event) => this._onElementDefocused(event));
} else {
this.element.removeEventListener('focus', (event) => this._onElementFocused(event));
this.element.removeEventListener('focusout', (event) => this._onElementDefocused(event));
}
}
as can be seen, the problem was not about aurelia and was about javascript context itself but was confusing me. Hope this helps others. TG.
Upvotes: 2