LWC/Aura/VFそれぞれでLightning Message Serviceを使ってみました。
簡単なメッセージのpublish/subscribeの仕方をまとめます。
参考文献はこちら
・LightningMessageChannel
・Create a Message Channel
・Message Service
・Communicating Across the DOM with Lightning Message Service
・Message Channel
・Lightning Message Service を使用した DOM 間の通信
あとはTrailhead Sample GallaryのLWC Recipesです。
以下のリポジトリにサンプルコードがあります。
##Message Channelのデプロイ
LMSを使用するには組織にMessageChannelメタデータをデプロイする必要があります。
以下の手順でデプロイしました。
- プロジェクトの
force-app/main/default
配下にmessageChannels
フォルダを作成 -
messageChannels
配下にmessageChannelName.messageChannel-meta.xmlファイルを作成 - ファイルの内容をメタデータAPIガイドを参照して設定
サンプルだと以下のような感じ。lightningMessageFieldにペイロードとして渡す項目を定義します。 - デプロイして完了
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<masterLabel>sampleMessageChannel</masterLabel>
<isExposed>true</isExposed>
<description>This is a sample Lightning Message Channel.</description>
<lightningMessageFields>
<fieldName>recordId</fieldName>
<description>This is the record Id that changed</description>
</lightningMessageFields>
<lightningMessageFields>
<fieldName>stringData</fieldName>
<description>string data for publish.</description>
</lightningMessageFields>
</LightningMessageChannel>
##LWCでのLMSの使用
LWCでLMSを使用するにはlightning/messageService
からpublishなどのモジュールをインポートする必要があります。
また、デプロイしたmessageChannelを'@salesforce/messageChannel/sampleMessageChannel__c'
の形でインポートする必要があります。
messagechannelを指定するときは__cを使用するようです。
import { publish, subscribe, MessageContext } from "lightning/messageService";
import SAMPLEMESSAGECHANNEL from "@salesforce/messageChannel/sampleMessageChannel__c";
###LWCでのpublish
インポートしたpublishモジュールを使用してpublishします。
wireで取得したmessageContextとインポートしたmessageChannel、ペイロードが必要になります。
詳しくはガイドに載ってますのでそちらをご参照ください。
以下、publishの例
const payload = { stringData: "Lightning Message from LWC" };
publish(this.messageContext, SAMPLEMESSAGECHANNEL, payload);
###LWCでのsubscribe
インポートしたsubscribeモジュールを使用してsubscribeします。
サンプルコードなどではconnectedCallback()
内でsubscribe関数を使用しているようです。
subscribe関数にはmessageContext、messageChannel、subscribeしたときに実行する関数などが必要になります。
connectedCallback() {
this.subscription = subscribe(
this.messageContext,
SAMPLEMESSAGECHANNEL,
(message) => this.handleMessage(message)
);
}
handleMessage(message) {
this.message = message.stringData;
}
##AuraコンポーネントでのLMSの使用
AuraコンポーネントでLMSを使用するにはlightning:messageChannel
をコンポーネントに記載します。
後述しますがこのコンポーネントとonMessageを設定するだけでsubscribeされるようになるのでLWCより使いやすい印象です。
<lightning:messageChannel
type="sampleMessageChannel__c"
onMessage="{!c.handleMessage}"
aura:id="messageChannel"
/>
###Auraでのpublish
publishするにはコンポーネント側で記載したlightning:messageChannel
のpublishメソッドを使用します。
publishメソッドにはpayloadのみ指定すればOKです。
findで探してくる必要があるためaura:id
の指定が必須となります。
var payload = { stringData: "Lightning Message from Aura" };
component.find("messageChannel").publish(payload);
###Auraでのsubscribe
subscribeするにはコンポーネント側でlightning:messageChannel
を記載し、onMessage
イベントに対してハンドラメソッドを指定します。
ハンドラメソッドにはcomponentとmessageを引数として受け取ることができ、messsage.getParam('fieldName')
の形でペイロードの中身を取得することができます。
<aura:attribute name="message" type="String" />
<lightning:messageChannel
type="sampleMessageChannel__c"
onMessage="{!c.handleMessage}"
aura:id="messageChannel"
/>
handleMessage: function (component, message) {
component.set("v.message", message.getParam("stringData"));
}
##VFでのLMSの使用
VFページでLMSを使用するにはjavascript内で$MessageChannel
変数を使用してmessageChannelを取得します。
また、sforce.oneオブジェクトを使用して上記で使用した変数と合わせてpublish/subscribeを行います。
(今回はVFコンポーネントとしてアプリケーションページに配置します)。
<script>
var SAMPLEMESSAGECHANNEL = "{!$MessageChannel.sampleMessageChannel__c}";
</script>
###VFでのpublish
Javascript内でsforce.one.publish
を使用します。
取得したmessageChannelとペイロードを指定します。
<script>
var payload = { stringData: "Lightning Message from VF" };
sforce.one.publish(SAMPLEMESSAGECHANNEL, payload);
</script>
###VFでのsubscribe
subscribeするにはsforce.one.subscribe
を使用します。
取得したmessageChannelとメッセージ受信時のハンドラメソッドを指定する必要があります。
<script>
window.onload = function () {
sforce.one.subscribe(SAMPLEMESSAGECHANNEL, handleMessage);
}
function handleMessage(message) {
document.getElementById("message").innerHTML = "Message: " + message.stringData;
}
</script>
最後に
Visualforceとも通信できるのはかなり便利ですね。
使い方をぜひとも覚えておきたいです。