Lifecycle
SALVO-TS components are Web Components, which means that they're associated with custom HTML elements (like <my-component>). When these elements are used on a page, the browser automatically creates the associated javascript class.
SALVO-TS automatically handles the core Web Component lifecycle and registering your components with the browser.
Below you can see a diagram of the full component lifecycle:
Lifecycle hooks
You can add methods to your components to hook in at various stages during the lifecycle:
typescript@Componentclass MyComponent extends ThemeComponent {// Runs when the component's element is added to the pageinit() {// Perform your setup - register event listeners, etc.}// Runs when the component's element is removed from the pagedestroy() {// Clean up any event listeners you've created and reverse any side-effects.}}
typescript@Componentclass MyComponent extends ThemeComponent {// Runs when the component's element is added to the pageinit() {// Perform your setup - register event listeners, etc.}// Runs when the component's element is removed from the pagedestroy() {// Clean up any event listeners you've created and reverse any side-effects.}}
A component is init() every time it's added to a page. If a component is moved in javascript, it'll be destroy() and then init() again in the new location.
Ensure that your component correctly cleans up any side effects (i.e. event listeners) each time it's destroyed.
Example
Here's an example of a well-behaving component:
typescript@Componentclass GreeterComponent extends BaseComponent {@Prop({required: false}) name?: string;@Prop({required: false}) dateOfBirth?: string;@Ref messageSpan: HTMLElement;popupComponent: null|PopupComponent = null;init() {this.messageSpan.textContent = `Hey, ${this.name || 'customer'}!`;// Register event handlersthis.customer.change.subscribe(this.handleCustomerChanged);// Create elementsthis.popupComponent = document.createElement('popup-component');document.body.appendChild(this.popupComponent);this.checkBirthday();}destroy() {// Unregister event handlersthis.customer.change.unsubscribe(this.handleCustomerChanged);// Clean up elementsthis.popupComponent.remove();}handleCustomerChanged(customer: null|Customer) {this.name = customer?.name;this.dateOfBirth = customer?.getDateOfBirth();this.checkBirthday();}checkBirthday() {if (!this.dateOfBirth || !this.popupComponent) {return;}if (moment(this.dateOfBirth).isToday()) {this.popupComponent.showPopup(`Happy birthday, ${this.name}!`);}}}
typescript@Componentclass GreeterComponent extends BaseComponent {@Prop({required: false}) name?: string;@Prop({required: false}) dateOfBirth?: string;@Ref messageSpan: HTMLElement;popupComponent: null|PopupComponent = null;init() {this.messageSpan.textContent = `Hey, ${this.name || 'customer'}!`;// Register event handlersthis.customer.change.subscribe(this.handleCustomerChanged);// Create elementsthis.popupComponent = document.createElement('popup-component');document.body.appendChild(this.popupComponent);this.checkBirthday();}destroy() {// Unregister event handlersthis.customer.change.unsubscribe(this.handleCustomerChanged);// Clean up elementsthis.popupComponent.remove();}handleCustomerChanged(customer: null|Customer) {this.name = customer?.name;this.dateOfBirth = customer?.getDateOfBirth();this.checkBirthday();}checkBirthday() {if (!this.dateOfBirth || !this.popupComponent) {return;}if (moment(this.dateOfBirth).isToday()) {this.popupComponent.showPopup(`Happy birthday, ${this.name}!`);}}}