Nipuna Gunathilake
Events are essential for communicating state in Web Components. In addition to supporting the standard event APIs in modern browsers, Polymer offers simpler ways of event handling. Also, Polymer automatically handles events required for data binding.
In Polymer, the usual pattern is to pass values down into child components through properties. And to pass changes up to parent components by using events.
The phrase properties go down, events go up is often used to describe this pattern. Following this pattern makes it possible to handle state changes in a predictable manner.
The mediator pattern is a behavioral pattern where a mediator object handles the communication between its child objects.
It’s recommended to use this pattern with Polymer Components. One mediator component (e.g.: my-component
) handles the communications between its child elements (e.g.: input
& h3
).
Annotated event listeners can be used to declaratively create event listeners
We’ve used this in the article introducing Polymer Properties. We can listen to events on child elements by having a property named on followed by the event name we want to listen to.
<dom-module id="my-element">
<template>
...
<div>
<button type="button" increment on-click="handleIncrement">+</button>
<span>[[value]]</span>
<button type="button" decrement on-click="handleDecrement">-</button>
</div>
</template>
<script>
class MyCounter extends Polymer.Element {
static get is() { return 'my-counter'; }
static get properties() {
return {
value: {
type: Number,
value: 0,
reflectToAttribute: true,
},
increment: {
type: Number,
value: 1,
}
};
}
handleIncrement() {
let incrementedValue = this.value + this.increment;
this.value = this.isInRange(incrementedValue) ? incrementedValue : this.value;
}
}
</script>
</dom-module>
In the above example, we call the handleIncrement
method when the click
event is fired in the button child element.
In Polymer components, how we listen to an event depends on its origin. Events from different origins are handled in the following ways:
ready
function.ready() {
super.ready();
this.addEventListener('click', this._onClick);
}
Child Elements – Event from a child element of the custom element. We can use annotated event listeners as discussed earlier.
Outside Elements – Event that’s from outside the scope of the custom element (e.g.: window
). For these events, we can add event listeners on connectedCallback
.
constructor() {
// we need to use handlers bound to the local 'this'
// to ensure that the 'this' context is properly set
_boundResizeHandler = resizeHandler.bind(this);
}
connectedCallback() {
super.connectedCallback();
window.addEventListener('resize', this._boundResizeHandler);
}
disconnectedCallback() {
super.disconnectedCallback();
// We must remove listeners to prevent memory leaks.
window.removeEventListener('resize', this._boundResizeHandler);
}
_boundResizeHandler
resizeHandler(e) {
// handle resize event here
console.log('resized');
}
Custom events can be called by creating a new CustomEvent
. This is a standard way of creating custom events in modern browsers. Polymer also provides a polyfill for supporting older browsers.
const event = new CustomEvent('my-event', {bubbles: true, composed: true});
We are setting the following two properties on the CustomEvent:
When an event is bubbled up from the inside of the Shadow DOM to its parent, that event becomes re-targeted.
Meaning that the parent sees the custom element itself as the target of the event. Even when the event is triggered by a child element that’s inside the custom element.
This enables the parent component to handle events without having knowledge of the Shadow DOMs’ structure. But we sometimes do need to find the real target.
If we need to identify the origin of the event, we can use the composedPath
property to do so. event.composedPath()
returns an array of elements that the event has bubbled through. The very first item in the returned array is the origin element.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.