I am learning about Aurelia for a few weeks now and I seem to have a data binding issue with a custom attribute.
I have created the following square
custom attribute (based on the examples from the "Templating:Custom Attributes" guide on the Aurelia website):
square.ts:
import { bindable, autoinject } from "aurelia-framework";
@autoinject
export class SquareCustomAttribute {
@bindable sideLength = "100px";
@bindable color = "red";
constructor(private element: Element) {
this.sideLengthChanged(this.sideLength);
this.colorChanged(this.color);
}
sideLengthChanged(newValue: string) {
if (this.element instanceof HTMLElement) {
this.element.style.width = this.element.style.height = newValue;
}
}
colorChanged(newValue: string) {
if (this.element instanceof HTMLElement) {
this.element.style.backgroundColor = newValue;
}
}
}
I would like this custom attribute to be usable without explicitly binding it, in which case it should use the default values, like in this consuming view:
app.html:
<template>
<require from="./square"></require>
<div square></div>
</template>
The code above works fine. It renders the div
as a square with 100px sides and a red background.
Problems arise when I set the color
property of SquareCustomAttribute
as the primary property (using @bindable
's configuration object parameter) like this:
Updated square.ts:
import { bindable, autoinject } from "aurelia-framework";
@autoinject
export class SquareCustomAttribute {
@bindable sideLength = "100px";
@bindable({ primaryProperty: true }) color = "red";
constructor(private element: Element) {
this.sideLengthChanged(this.sideLength);
this.colorChanged(this.color);
}
sideLengthChanged(newValue: string) {
if (this.element instanceof HTMLElement) {
this.element.style.width = this.element.style.height = newValue;
}
}
colorChanged(newValue: string) {
if (this.element instanceof HTMLElement) {
this.element.style.backgroundColor = newValue;
}
}
}
For some reason, setting color
as the primary property of the custom attribute, the colorChanged
callback gets invoked twice now: first by the constructor with the default value and then once more from somewhere in the lifecycle initialization with an empty value.
How can I avoid this second invocation of the colorChanged
callback, so that the default value of the primary property of my custom attribute will not be cleared when I do not explicitly supply a binding/value of the square
attribute in the consuming view's HTML markup?