Ga naar hoofdinhoud

Events in Polymer

Nov 30, 2016
3 minutes

When playing around in Polymer, we encounter iron signals. Besides normal javascript events, this gives us a lot of options for dealing with events.

<!-- more -->

Lets try it all out! We can catch events using the on-event attribute:

// prettier-ignore
1
javascript

This calls method push1:

{
	push1: function () {
		console.log("sub-component1: button 1 pushed. Using the on-tap property");
	},
};
javascript

Scroll down for the complete code listing. Or see it on github. Another way to catch it is using a listener:

// prettier-ignore
2
javascript
{
	listeners: {
		"button2.tap": "push2",
	},

	push2: function () {
		console.log("sub-component1: button 2 pushed. Using a listener");
	},
};
javascript

We can also fire our own events:

{
	push3: function () {
		this.fire("push3");
	},
};
javascript

We can catch that in the parent component using the on-event attribute or a listener. These events will always bubble up to parent components. Even when the event is caught. But never sideways. So in this situation the methods push, push-parent and push-grandparent will be called, but not push-sibling.

// prettier-ignore
1
// prettier-ignore
2
javascript

So it's good to not use too generic names, because the parent component might also use that event. You can prevent that by prefixing your event names with your component name. you can stop an event from bubbling up by using event.stopPropagation():

{
	push5: function (event) {
		event.stopPropagation();
		console.log(
			"sub-component1: button 5 pushed. This stops the event from bubbling upward.",
		);
	},
};
javascript

You can also use iron-signals to throw events sideways. Throw them:

{
  this.fire("iron-signal", { name: "push4", data: null });
}
javascript

and catch them:

You can also catch them in multiple places. I recommend against using iron-signals, because it can be hard to find out where the even comes from or will be caught. Use the rule of least power and stay with normal javascript events. Complete code. Polymer-events.html:

Polymer({
  is: "polymer-events",
  listeners: {
    push3: "push3b",
  },

  push3a: function () {
    console.log(
      "polymer-events: button 3 pushed. Using a custom javascript event and the on-push3 property.",
    );
  },

  push3b: function () {
    console.log(
      "polymer-events: button 3 pushed. Using a custom javascript event and a listener.",
    );
  },

  push4: function () {
    console.log("polymer-events: button 4 pushed. Using iron-signals.");
  },

  tapSubcomponent1: function () {
    console.log(
      "polymer-events: tapSubcomponent1. This also happens when a specific button tap is already caugth in subComponent1. Events always bubble up.",
    );
  },
});
javascript

This uses subComponent1:

Polymer({
  is: "sub-component1",

  listeners: {
    "button2.tap": "push2",
  },

  push1: function () {
    console.log("sub-component1: button 1 pushed. Using the on-tap property");
  },

  push2: function () {
    console.log("sub-component1: button 2 pushed. Using a listener");
  },

  push3: function () {
    this.fire("push3");
  },

  push4: function () {
    this.fire("iron-signal", { name: "push4", data: null });
  },

  push5: function (event) {
    event.stopPropagation();
    console.log(
      "sub-component1: button 5 pushed. This stops the event from bubbling upward.",
    );
  },
});
javascript

and subComponent2:

Polymer({
  is: "sub-component2",

  listeners: {
    push3: "push3",
  },

  push3: function () {
    console.log(
      "sub-component2: button 3 pushed. This will not happen because javascript events only go upwards in the element hierarchy.",
    );
  },

  push4: function () {
    console.log("sub-component2: button 4 pushed. Using iron-signals.");
  },
});
javascript