Salesforce ハックチャレンジ 2014でLightningMessageを実装したとき、少しハマったのでLightningイベントとDOMイベントでコントローラアクションを呼び出したときにイベント発生元要素の情報を取得する方法についてまとめておきます。
LightningイベントとDOMイベント
まずLightningイベントとDOM要素イベントについて説明します。
Lightningイベントとは、Lightningコンポーネントを操作した時に発生するイベントで、DOM要素イベントはブラウザのDOM要素イベントです。
Lightningイベントは自動的にコントローラ(Controller.js)に定義したコントローラアクションと紐付けることができます。同様にonで始まるブラウザのDOM要素イベントてもコントローラ(Controller.js)に定義したコントローラアクションと紐付けることができます。
イベント発生元要素の取得
イベント発生元となる要素の取得方法が異なりますので注意が必要です。
Lightningコンポーネントの場合
event.getSourceが定義されており、event.getSource()でLightningコンポーネントが取得できます。LightningコンポーネントのDOM要素は、event.getSource().getElement()で取得できます。DOM要素まで取得できれば、あとは属性を取得するだけですが、Lightningコンポーネントの場合記述できない属性もあります。
DOM要素の場合
event.getSourceが定義されていません。event.targetでDOM要素を取得することができます。
ボタンの場合はそのまま取得できますが、<div>にリンクをつけている場合などは、イベント発生元要素が<div>のほうになります。<a>にidなどのつけている場合は、parentNodeを辿っていく必要があります。
サンプルコード
<aura:application>
<!-- Lightningイベント -->
<div>
<ui:button label="Framework Button" press="{!c.handleClick}"/>
</div>
<!-- DOMイベント -->
<div>
<input type="button" value="Html Button" onclick="{!c.handleClick}"/>
</div>
<div>
<a id="link1" onclick="{!c.handleClick}">
<div>Click me!</div>
</a>
</div>
</aura:application>
({
handleClick : function(component, event, helper) {
if(event.getSource) {
console.log("event.getSource()");
console.log(event.getSource());
console.log("event.getSource().getElement()");
console.log(event.getSource().getElement());
} else {
console.log("target");
console.log(event.target);
console.log("target.parentNode");
console.log(event.target.parentNode);
console.log("target.parentNode.id");
console.log(event.target.parentNode.id);
}
}
})
まとめ
LightningイベントとDOM要素イベントでイベント発生元要素の取得方法が異なってきますので、LightningコンポーネントかDOM要素か注意して書き分ける必要があります。
Bootstrapなどを利用すると一覧表示して一覧の中から1つの要素をクリックするような動作は<div>と<a>で記述し、行ごとにidなどを指定して画面遷移先に表示するデータを切り替えます。そのため、実際に処理を記述するとDOM要素イベントを扱うことも多くなってきます。
現在は、ボタンやテキストボックスなど明示的に見える要素のみ組み込みのコンポーネントが準備してありますが、アクションを記述することが多い<a>にもコンポーネントを用意してあるとよりシンプルに書けるようになって嬉しいなぁと思いました(パラメータ付きのイベントやアクションになってほしい)。