2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【LWC】Lightning Message Service使ってみた

Last updated at Posted at 2021-09-04

#Lightning Message Serviceとは
Lightningページ内でDOM全体の通信を行うものです。LWCは複数のコンポーネントを使用してページを構成することが多いですが、その時にコンポーネント間でPub-Sub方式で通信をすることが出来ます。ちなみにLWCだけでなく、VisualforceやAuraコンポーネントでも通信が出来ますが今回はLWC間で通信を行います。
#作成するもの
今回作成するものは取引先をクリックしたら、その取引先の取引先責任者を表示するものです。1画面であればなんてことないものですが、2つのコンポーネントに跨る場合はMessage Serviceが必要になります。
####初期画面
image.png
####一番上の取引先をクリック
image.png
右のコンポーネントに取引先に紐づく取引先責任者が表示される。

#メッセージチャネルの作成
Lightning Message Serviceを使用するにはLightningMessageChannelメタデータ型を定義する必要があるそうです。force-app/main/defaultにmessageChannelsディレクトリを作成し、xmlファイルを作成します。

SampleMessageChannel.messageChannel-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
    <description>This is a sample Lightning Message Channel for the Lightning Web Components.</description>
    <isExposed>true</isExposed>
    <lightningMessageFields>
        <description>This is the record Id that changed</description>
        <fieldName>recordId</fieldName>
    </lightningMessageFields>
    <masterLabel>SampleMessageChannel</masterLabel>
</LightningMessageChannel>

masterLabelに任意の名前を入力します。

#取引先のリスト
まずは左側のコンポーネントです。こちらはメッセージを公開する側です。

accountList.html
<template>
    <lightning-card title="Account List" icon-name="custom:custom1">
      <div class="slds-m-around_medium" onaccountselect={handleAccountSelect}>
        <template if:true={account.data}>
          <template for:each={account.data} for:item="acc">
            <c-account-list-item key={acc.Id} account={acc}></c-account-list-item>
          </template>
        </template>
      </div>
    </lightning-card>
</template>
accountList.js
import { LightningElement, wire } from 'lwc';
import getAccountList from '@salesforce/apex/AccountTableViewController.getAccountList';
import { publish, MessageContext } from 'lightning/messageService';
import SampleMC from '@salesforce/messageChannel/SampleMessageChannel__c';

export default class AccountList extends LightningElement {
  @wire(getAccountList)
  account;

  @wire(MessageContext)
  messageContext;

  handleAccountSelect(event) {
    console.log('select');
    const payload = { recordId: event.target.account.Id };
    publish(
      this.messageContext, 
      SampleMC, 
      payload
    )
  }
}

下記の2行でpublishとMessageContextと、先ほど作成したメタデータをimportします。作成したメタデータファイル名の最後に「__c」をつけないといけないらしいです。

import { publish, MessageContext } from 'lightning/messageService';
import SampleMC from '@salesforce/messageChannel/SampleMessageChannel__c';

@wire(MessageContext)でMessageContextオブジェクトを作成します。payloadが今回右側のコンポーネントに渡す取引先のIdになります。ここは形式を覚えておけば大丈夫です。
#取引先責任者のリスト
こちらはメッセージを受け取る側のコンポーネントです。

contactDetail.js
import { LightningElement, wire } from 'lwc';
import getContacts from '@salesforce/apex/ContactHandler.getContacts';
import { subscribe, unsubscribe, APPLICATION_SCOPE, MessageContext } from 'lightning/messageService';
import SampleMC from '@salesforce/messageChannel/SampleMessageChannel__c';

export default class ContactDetail extends LightningElement {
  subscription = null;
  recordId;

  @wire(getContacts, {accId : '$recordId'})
  contacts;

  @wire(MessageContext)
  messageContext;

  // messageを購読
  subscribeToMessageChannel() {
    if(!this.subscription) {
      this.subscription = subscribe(
        this.messageContext,
        SampleMC,
        (message) => this.recordId = message.recordId,
        {scope: APPLICATION_SCOPE}
      );
    }
  }

  unsubscribeToMessageChannel() {
    unsubscribe(this.subscription);
    this.subscription = null;
  }

  connectedCallback() {
    this.subscribeToMessageChannel();
  }

  disconnectedCallback() {
    this.unsubscribeToMessageChannel();
  }
}

受け取る側では下記2行をインポートします。

import { subscribe, unsubscribe, APPLICATION_SCOPE, MessageContext } from 'lightning/messageService';
import SampleMC from '@salesforce/messageChannel/SampleMessageChannel__c';

connectedCallbackでsubscribeToMessageChannelを呼び出し、メッセージを購読します。今回の場合はrecordIdですのでmessage.recordIdをthis.recordIdに代入します。あとは@wireを使用して取引先責任者のレコードを取得して表示するだけです。

Pub-Sub方式になじみがなかったのではじめは戸惑いましたが、メッセージのやり取りのイメージさえ掴めればそこまで難しくないです。どの程度使用する機会があるか分かりませんが、使い道はある気がします。

ソースコード:https://github.com/KZ63/Salesforce

#参考
https://developer.salesforce.com/docs/component-library/documentation/ja-jp/lwc/lwc.use_message_channel

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?