LoginSignup
1
1

LMS (Lightning Message Service)を使ってみた

Posted at

背景

LMS (Lightning Message Service)を利用してみたいという気持ちはずっとありましたが、Parent-Child間でほぼ済んでいたので、無関係なコンポーネント間のデータのやり取りニーズは正直ありませんでした。

今回その必要性が出てきたのですが、その前に、標準の関連リストが簡単でお気に入りである一方、どうしても一括編集などができないのでlightning-datatableのonrowactionやdraft-valuesを利用した一括編集のできる関連リスト(LWC)をカスタムで作成していました。

そこで、さらにQuickActionからFlowを起動して複数の関連レコードを作成する機会があり、QuickActionからフローを起動してレコードを作成したのですがここで問題が発生です。

標準リストでは新規に作成したレコードも含めてリストを自動で更新しますが、カスタム関連リストでは更新しません。これは、なにかしらLWCヘ新規レコードが作成されたということを通知する必要があり、LMSで解決できそうではないかと思ったわけです。

結果

結果は、LMSでFlowのステータスが「FINISHED」が帰ってきた時にpublishし、カスタム関連リストのLWCにその旨を通知して、subscribe側のLWCで再度情報を取得するメソッドを走らせることで、リストが無事更新されることになりました。標準関連リストに寄せてカスタムを作成すると大変だなぁという感想です。

ただこのLMSは取得したデータをどんな型でも送れるので、あるコンポーネントのデータ群を親子関係でない別のコンポーネントへ送って描画する場合にも利用できるのではないかと考えています。

デモ

  1. LWCを起動するQuick ContactのQuick Actionボタンを押すと、LWCのModalが出現して、データをInputします。(Screen Flow)
  2. Flowを完了するとlightning-flowのonstatuschangeで、FINISHEDのステータスがLWCに戻ってきて、MessageChannelでpublishします。
  3. MessageChannelを通じて別のLWCが通知をsubscribeして、データ更新のメソッドを走らせます。今回はshowToastでSubscribedした旨も通知です。

subscribe.gif

構成

Screen Flow * 1
Quick Action * 1
Class * 1
LWC * 2
Message Channel * 1
以上です。

手順

1. Flowを内包したLWCを作成

<template>
    <lightning-card title={title} icon-name={iconName}>
        <div class="slds-m-top_small">
            <lightning-flow lwc:if={recordId} flow-api-name={flowName} flow-input-variables={inputVariables}
                onstatuschange={handleFlowFinish}></lightning-flow>
        </div>
    </lightning-card>
</template>

2. QuickActionからはLWC経由でフローを起動

Flow API Name はこちらを参照
Screenshot 2024-01-13 at 16.52.02.png
Screen Flowで入力画面から値を代入
Screenshot 2024-01-13 at 16.53.19.png

recordIdはFlow外部からの入力を可にします。LWCからinputVariablesとして入ってくるIdを受け止めるためです。
Screenshot 2024-01-14 at 11.59.56.png

3. Flowが終わったらフローのステータスを取得

  handleFlowFinish(event) {
    if (event.detail.status === "FINISHED") {
      const message = {
        recordId: this.recordId,
        status: event.detail.status,
      };
      this.dispatchEvent(new CloseActionScreenEvent());

      // Publish the message
      publish(this.messageContext, FINISH_FLOW_CHANNEL, message);
    }
  }

recordIdですが、通常は@api recordIdで取得できますが、今回はScreen Action (Ui action)なので、renderedされて初めて取得されます。よってgetter, setterで設定します。と同時にinputVariablesにそのrecordIdを取得後挿入して、lightning-flowを起動します。

  inputVariables = [];

  _recordId;
  @api
  get recordId() {
    return this._recordId;
  }

  set recordId(value) {
    if (value !== this._recordId) {
      this._recordId = value;
      this.inputVariables = [
        {
          name: "recordId",
          type: "String",
          value: value,
        },
      ];
    }
  }

4. LMSにmessageを送信

上記と合わせてpublishするためにjsにimportしておきます。
Publish側 (createContactQuickAction)

import { publish, MessageContext } from "lightning/messageService";
import FINISH_FLOW_CHANNEL from "@salesforce/messageChannel/finishFlow__c";

messageChannels
VS Codeのforce-app/main/default/ 下に手動でmessageChannelsというfolderを作成して、その中にmessageChannel-meta.xmlを登録する必要があります。
Screenshot 2024-01-13 at 18.13.50.png

5. カスタム関連リストがLMS経由でpublisherのmessageを受け取る

Subscribe側 (getContactList)

import { subscribe, MessageContext } from "lightning/messageService";
import FINISH_FLOW_CHANNEL from "@salesforce/messageChannel/finishFlow__c";

6. 情報取得methodを動かして更新

messageが来るのを@wireで監視します。

  @wire(MessageContext)
  messageContext;
  subscription = null;
  subscribeToChannel() {
    // Subscribe to the message channel
    if (this.subscription) {
      return;
    }
    this.subscription = subscribe(
      this.messageContext,
      FINISH_FLOW_CHANNEL,
      (message) => this.handleMessage()
    );
  }

  // Subscribing to the message channel debug
  handleMessage() {
    this.handleGetContacts(); // to refresh the datatable
    const params = {
      message: "Subscribed Successfully",
      mode: "dismissable",
      variant: "success",
    };
    this.handleShowToast(params);
  }

参照

Use Quick Actions - Screen Flow (Salesforce)
Lightning Flow (Salesforce)
Lightning Datatable (Salesforce)
LMS Component Library (Salesforce)
Lightning Message Service(LMS)を触ってみました (TerraSky)

まとめ

これは以前の投稿した商品の値段や個数を自由に変更できる「商品追加ボタン」を作ってみた (lwc)での商談商品の再取得にも利用できそうです。

標準ではFlowで作成した新規はすぐに関連リストに表示されます。Inline Editをさせてくれれば最高なんですが、それゆえにListEditorとかの利用需要があるものわかります。

自動更新は、Master-detailの集計項目があればそれを@wireで絡めて、新規データが追加されるごとのデータ取得を走らせることもできます。今回は単にLookup関係でもできるようにしました。

難易度的には簡単な方から:

  1. related list
  2. mater-detail relationship with @wire
  3. Lightning Message Service
    でした。

Lightning Message Serviceを学べてとても楽しかったです。
githubにコードを公開しておきますので、もしアイディアのある方がいたらぜひ。
https://github.com/liuxiachanghong/lightning-message-service

1
1
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
1
1