ConductedClever
ConductedClever

Reputation: 4295

Aurelia change on own property does not call changed listener

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

Answers (1)

ConductedClever
ConductedClever

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

Related Questions