Component Attributes
Attributes and Properties
When a new attribute is added to the component, ElementalComponent
automatically exposes it as a class property.
If the attribute is designated as observable by either overriding the observedAttributes
static getter, or by using the @ObservedState
decorator, the attribute and property will remain in sync with any data updates.
Observing a Property
👺 Choose only one approach
Either use @ObservedState
or override the static get observedAttributes()
. Do not mix and match.
By using @ObservedState
decorator
@Component
class Hero extends ElementalComponent {
@ObservedState
private superpower = 'unknown';
// rest of the code ommitted for brevity...
}
@Component
class Hero extends ElementalComponent {
@ObservedState
private superpower = 'unknown';
// rest of the code ommitted for brevity...
}
By Overriding the static observedAttributes
getter
@Component
class Hero extends ElementalComponent {
static get observedAttributes() {
return ['superpower'];
}
private superpower = 'unknown';
// rest of the code ommitted for brevity...
}
@Component
class Hero extends ElementalComponent {
static get observedAttributes() {
return ['superpower'];
}
private superpower = 'unknown';
// rest of the code ommitted for brevity...
}
Updating an Observed Property
ElementalComponent
overrides the attributeChangedCallback(...)
lifecycle hook to listen to property changes and these changes are triggered only when the attribute value is updated via the native setAttribute(...)
API.
Hence, the correct way to update an observed property is to call the this.setAttribute('property-name', 'property-value');
API.
Example
In the following example, note that there are three attributes used in the HTML code. id
, name
, and superpower
. Only superpower
attribute is made an observable.
When the superpower
attribute change is detected, the corresponding class property this.superpower
also gets updated.
<!-- somewhere in index.html -->
<el-hero id="one" name="Superman" superpower="Laser Eyes"></el-hero>
<!-- somewhere in index.html -->
<el-hero id="one" name="Superman" superpower="Laser Eyes"></el-hero>
import { Component, ElementalComponent, ObservedState } from '@sohailalam2/elemental-web';
@Component
class Hero extends ElementalComponent {
private name = 'unknown';
@ObservedState
private superpower = 'unknown';
protected render() {
this.$root.innerHTML = `
<p>I am ${this.name} and I have ${this.superpower}</p>
`;
}
protected connectedCallback() {
super.connectedCallback();
// simulating an update after 2 seconds
setTimeout(() => {
// ✅ Correct way, will auto update the DOM
this.setAttribute('superpower', 'XRay Vision');
// ❌ Wrong way... this will not update the DOM
this.superpower = 'Super Hearing';
}, 2000);
}
}
import { Component, ElementalComponent, ObservedState } from '@sohailalam2/elemental-web';
@Component
class Hero extends ElementalComponent {
private name = 'unknown';
@ObservedState
private superpower = 'unknown';
protected render() {
this.$root.innerHTML = `
<p>I am ${this.name} and I have ${this.superpower}</p>
`;
}
protected connectedCallback() {
super.connectedCallback();
// simulating an update after 2 seconds
setTimeout(() => {
// ✅ Correct way, will auto update the DOM
this.setAttribute('superpower', 'XRay Vision');
// ❌ Wrong way... this will not update the DOM
this.superpower = 'Super Hearing';
}, 2000);
}
}