ポリマーでのイベントの処理
イベントは、Webコンポーネントで状態を通信するために不可欠です。 最新のブラウザで標準のイベントAPIをサポートすることに加えて、Polymerはイベント処理のより簡単な方法を提供します。 また、Polymerはデータバインディングに必要なイベントを自動的に処理します。
ポリマーのイベント
Polymerでは、通常のパターンは、プロパティを介して値を子コンポーネントに渡すことです。 また、イベントを使用して変更を親コンポーネントに渡します。
このパターンを説明するために、プロパティがダウンし、イベントがアップというフレーズがよく使用されます。 このパターンに従うことで、予測可能な方法で状態の変化を処理することが可能になります。
メディエーターパターン
メディエーターパターンは、メディエーターオブジェクトがその子オブジェクト間の通信を処理する動作パターンです。
このパターンは、ポリマーコンポーネントで使用することをお勧めします。 1つのメディエーターコンポーネント(例:my-component
)子要素間の通信を処理します(例:input
&h3
)。
注釈付きイベントリスナー
注釈付きのイベントリスナーを使用して、宣言的にイベントリスナーを作成できます
これは、ポリマープロパティを紹介する記事で使用しました。 on という名前のプロパティの後に、リッスンするイベント名を指定することで、子要素のイベントをリッスンできます。
<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>
上記の例では、ボタンの子要素でclick
イベントが発生したときに、handleIncrement
メソッドを呼び出します。
イベントを聞く
Polymerコンポーネントでは、イベントをどのようにリッスンするかは、その発生源によって異なります。 さまざまな発生源からのイベントは、次の方法で処理されます。
- カスタム要素–カスタム要素自体からのイベント。
ready
関数にイベントリスナーを追加できます。
ready() {
super.ready();
this.addEventListener('click', this._onClick);
}
-
子要素–カスタム要素の子要素からのイベント。 前に説明したように、注釈付きのイベントリスナーを使用できます。
-
Outside Elements –カスタム要素のスコープ外からのイベント(例:
window
)。 これらのイベントについては、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');
}
カスタムイベントの発火
新しいCustomEvent
を作成することにより、カスタムイベントを呼び出すことができます。 これは、最新のブラウザでカスタムイベントを作成する標準的な方法です。 Polymerは、古いブラウザをサポートするためのポリフィルも提供します。
const event = new CustomEvent('my-event', {bubbles: true, composed: true});
CustomEventに次の2つのプロパティを設定しています。
- bubblesイベントがDOMを介してバブルすることを許可します。
- composed Shadow DOM境界を介したバブリングを許可します。これをtrueに設定すると、イベントがメインDOMによってインターセプトされます。
イベントのリターゲティング
イベントがShadowDOMの内部からその親にバブルアップされると、そのイベントは再ターゲットになります。
親がカスタム要素自体をイベントのターゲットと見なすことを意味します。 カスタム要素内にある子要素によってイベントがトリガーされた場合でも。
これにより、Shadow DOMの構造を知らなくても、親コンポーネントがイベントを処理できるようになります。 しかし、実際のターゲットを見つける必要がある場合もあります。
ComposedPath
イベントの発生源を特定する必要がある場合は、composedPath
プロパティを使用して特定できます。 event.composedPath()
は、イベントがバブルスルーした要素の配列を返します。 返される配列の最初の項目はorigin要素です。