Web Component API
To register for events, the on method on a ComponentClass
lets you define a class level event handler for all instances of that component. The supplied function can expect a webComponent
instance passed into it pertaining to an individual instance.
In the following example, the custom-status-component
is registered via a template, and then configured to set a custom alertType
on init
, on dataLoadSuccess
, and on dataLoadFailed
.
<template for="custom-status-component" refresh-time="5">
<button type="button" class="btn btn-{{alertType}}">
<span>{{content}}</span>
</button>
</template>
<script type="text/javascript">
$(function() {
var CustomStatusComponent = Component.configure("custom-status-component");
CustomStatusComponent.on("waitingForServer", function(instance) {
instance.alertType = "info";
});
CustomStatusComponent.on("dataLoadSuccess", function(instance) {
instance.alertType = "success";
});
CustomStatusComponent.on("dataLoadFailed", function(instance) {
instance.alertType = "danger";
});
});
</script>
The this
context for the event handler will always be the web component instance.
If you want to manually fire an event, or trigger a custom event, you can use the dispatchEvent(eventName)
command on an instance. This will cause any event handlers that have been registered to fire.
In the following example the ComponentClass.apply(fn)
method is used to trigger an init
event on all custom-button-component
instances on the page.
<custom-button-component>Hello John</custom-button-component>
<custom-button-component>Hello Anna</custom-button-component>
<custom-button-component>Hello Elmira</custom-button-component>
<template for="custom-button-component" refresh-time="5">
<button type="button" class="btn btn-{{alertType}}">
<span>{{content}}</span>
</button>
</template>
<script type="text/javascript">
$(function() {
var ButtonComponent = Component.configure("custom-button-component");
// Associate a static method for handling click events
ButtonComponent.handleClick = function(instance) {
alert("The button says: " + instance.content);
}
// Register the init method with something interesting
ButtonComponent.on('init', function(instance) {
instance.element.onclick = function() {
ButtonComponent.handleClick(instance);
};
});
// Trigger the init event on all existing ButtonComponent instances
ButtonComponent.apply(function(instance) {
instance.dispatchEvent("init");
});
});
</script>
The init
event is fired when a new component of ComponentClass
is created. If you are using templates and inline elements to define your components, then this will trigger on page load before you have chance to hook into the event.
The dataSourceUpdate
event is fired any time updateDataSourceStatus
is fired with a new message.
<script type="text/javascript">
$(function() {
var DataComponent = Component.configure("custom-data-component");
// Log a message to the console on every dataSourceUpdate
DataComponent.on('dataSourceUpdate', function(instance) {
console.log("Data source update on " + instance.webComponentId + ": " + instance.dataSourceMessage);
});
});
</script>
The waitingForServer
event is fired when a data load request has been started by an adapter.
The dataLoadSuccess
event is fired when a data load returns with data.
The dataLoadFailed
event is fired when data flat out fails to load, due to bad network, or a bad response from the server.
The dataReturnedError
event is fired when data is loaded successfully, but the data.error
property was set to a non falsey value.
The dataUnexpectedFormat
event is fired when the returned data is null
or not an object.
The dataLoadCompleteOnMissingElement
is fired if a data load completes on an element that is no longer attached to the DOM.
The component will then be deregistered for the garbage collector to pick up.
The preRenderStep
event is fired just before calling the body of the render function and expanding the template. This event hook is useful for applying some client side transformations to data immediately before rendering, for example mapping numeric values to CSS classes for styling purposes.
<custom-status-component status-code="200">Am I ok?</custom-status-component>
<custom-status-component status-code="400">Not ok?</custom-status-component>
<custom-status-component status-code="300">Informative?</custom-status-component>
<custom-status-component status-code="500">Warning?</custom-status-component>
<template for="custom-status-component">
<span class="btn btn-{{alertType}}">{{content}}</span>
</template>
<script type="text/javascript">
$(function() {
var StatusComponent = Component.configure("custom-status-component");
// Map data.statusCode to alertType immediately before rendering
StatusComponent.on('preRenderStep', function(instance) {
var severity = Math.round(instance["status-code"] / 100) * 100;
instance.alertType = ({
"0": 'info',
"100": 'primary',
"200": 'success',
"300": 'info',
"400": 'danger',
"500": 'warning'
})[severity] || 'danger';
});
// Force a re-render now
StatusComponent.apply(function(instance) {
instance.render();
});
});
</script>
The renderComplete
event is fired at the end of the render function. This event hook is useful for attaching additional JavaScript to the template post-instance creation. If you need to force a rerender immediately after page load, then you can use the ComponentClass.apply(fn)
method to achieve this.
<custom-clickable-component>Hello John</custom-clickable-component>
<custom-clickable-component>Hello James</custom-clickable-component>
<custom-clickable-component>Hello Hatty</custom-clickable-component>
<template for="custom-clickable-component">
<span class="btn btn-default">{{content}}</span>
</template>
<script type="text/javascript">
$(function() {
var ClickableComponent = Component.configure("custom-clickable-component");
// Map data.statusCode to alertType immediately before rendering
ClickableComponent.on('renderComplete', function(instance) {
instance.element.onclick = function() {
alert("You clicked me: " + instance.content);
}
});
// Force all components to re-render
ClickableComponent.apply(function(instance) {
instance.render();
});
});
</script>