命令としての Apex メソッドのコール

メソッド呼び出しのタイミング (ボタンのクリックに対応するなど) を制御するには、命令としてメソッドをコールします。命令としてメソッドをコールすると、1 つの応答のみを受け取ります。フレームワークに制御を委任し、値のストリームがプロビジョニングされる @wire と、この動作を比較します。

次のシナリオでは、@wire を使用せずに命令としてメソッドを Apex コールする必要があります。

  • データを挿入、更新、削除するメソッドが含まれる、cacheable=true が付加されていないメソッドをコールする。
  • 呼び出しのタイミングを制御する。
  • ユーザインターフェース API でサポートされていないオブジェクト (ToDo や行動など) を操作する。
  • LightningElement を拡張しない ES6 モジュールのメソッドをコールする。

Apex メソッドが @AuraEnabled(cacheable=true) でマークされている場合、ネットワークコールを発行してサーバの Apex メソッドを呼び出す前にクライアント側の Lightning データサービスキャッシュがチェックされます。ただし、Apex によってプロビジョニングされるデータは Lightning データサービスでは管理されません。したがって、古いデータを更新するには、Apex メソッドを呼び出してから notifyRecordUpdateAvailable(recordIds) をコールし、Lightning データサービスキャッシュを更新します。

Apex メソッドのコール 

前の例と同じ getContactList クラスを使用する、lwc-recipes リポジトリのサンプルコンポーネントを見てみましょう。このクラスを結び付けるのではなく、ユーザがボタンをクリックしたときにコンポーネントで getContactList() をコールします。

[Load Contacts (取引先責任者を読み込む)] ボタンと、その下に表示された取引先責任者のリスト。

インポートされた関数は Promise を返します。このコードは一連のパラメータを前提として 1 回限りの解決策を提供しますが、@wire(apexMethod) は値のストリームを提供し、動的パラメータをサポートします。

1// apexImperativeMethod.js
2import { LightningElement, track } from "lwc";
3import getContactList from "@salesforce/apex/ContactController.getContactList";
4
5export default class ApexImperativeMethod extends LightningElement {
6  @track contacts;
7  @track error;
8
9  handleLoad() {
10    getContactList()
11      .then((result) => {
12        this.contacts = result;
13      })
14      .catch((error) => {
15        this.error = error;
16      });
17  }
18}
1public with sharing class ContactController {
2    @AuraEnabled(cacheable=true)
3    public static List<Contact> getContactList() {
4        return [
5            SELECT Id, Name, Title, Phone, Email, Picture__c
6            FROM Contact
7            WHERE Picture__c != NULL
8            WITH SECURITY_ENFORCED
9            LIMIT 10
10        ];
11    }
12}

このテンプレートは lwc:if を使用して、取引先責任者のリストまたはエラーパネルを表示します。また、for:each を使用して、取引先責任者を反復処理します。

1<!-- apexImperativeMethod.html -->
2<template>
3  <lightning-card title="ApexImperativeMethod" icon-name="custom:custom63">
4    <div class="slds-m-around_medium">
5      <p class="slds-m-bottom_small">
6        <lightning-button label="Load Contacts" onclick={handleLoad}></lightning-button>
7      </p>
8      <template lwc:if={contacts}>
9        <template for:each={contacts} for:item="contact">
10          <p key={contact.Id}>{contact.Name}</p>
11        </template>
12      </template>
13      <template lwc:elseif={error}>
14        <c-error-panel errors={error}></c-error-panel>
15      </template>
16    </div>
17  </lightning-card>
18</template>

パラメータを含む Apex メソッドのコール 

Apex メソッドにパラメータ値を渡すには、Apex メソッドのパラメータと一致するプロパティを持つオブジェクト内でパラメータ値を渡します。たとえば、Apex メソッドが文字列パラメータを取る場合、文字列を直接渡さず、値が文字列であるプロパティを含むオブジェクトを渡します。

検索項目に文字を入力し、[検索] をクリックすると、取引先責任者のリストが返されます。

1// apexImperativeMethodWithParams.js
2
3import { LightningElement } from "lwc";
4import findContacts from "@salesforce/apex/ContactController.findContacts";
5
6export default class ApexImperativeMethodWithParams extends LightningElement {
7  searchKey = "";
8  contacts;
9  error;
10
11  handleKeyChange(event) {
12    this.searchKey = event.target.value;
13  }
14
15  handleSearch() {
16    findContacts({ searchKey: this.searchKey })
17      .then((result) => {
18        this.contacts = result;
19        this.error = undefined;
20      })
21      .catch((error) => {
22        this.error = error;
23        this.contacts = undefined;
24      });
25  }
26}
1public with sharing class ContactController {
2    @AuraEnabled(cacheable=true)
3    public static List<Contact> findContacts(String searchKey) {
4        String key = '%' + searchKey + '%';
5        return [
6            SELECT Id, Name, Title, Phone, Email, Picture__c
7            FROM Contact
8            WHERE Name LIKE :key AND Picture__c != NULL
9            WITH SECURITY_ENFORCED
10            LIMIT 10
11        ];
12    }
13}

lwc-recipes リポジトリには、パラメータを使用してメソッドをコールする apexImperativeMethodWithParams コンポーネントもあります。オブジェクトパラメータを使用してメソッドをコールするには、apexImperativeMethodWithComplexParams コンポーネントを参照してください。

Tip

Apex への値の受け渡し 

レコードデータなどの値を LWC から Apex に渡すときは、JavaScript オブジェクトまたは配列を使用します。Apex メソッドに渡されるときに、対応付けの値はシリアライズされません。

命令 Apex コールおよび結び付けられた Apex コールでは、対応付けの使用はサポートされていません。map[key] = val などで対応付けを不適切に使用すれば、LWS を無効にしてデータを渡すことができました。しかし、LWS が有効のときは、このような方法は使用できなくなりました。また、Apex に値を渡す場合、map.set(key, val) はサポートされません。

1//Don’t do this
2Map map = new Map();
3map.set(key, val);
4apexMethod({map});

JavaScript オブジェクトを次のように使用することができます。

1import { LightningElement, wire } from "lwc";
2import apexMethod from "@salesforce/apex/ReadValues.apexMethod";
3
4export default class ApexValueExample extends LightningElement {
5  objVal = {};
6
7  val;
8
9  async connectedCallback() {
10    this.objVal["one"] = "two";
11    this.val = await apexMethod({ theValues: this.objVal });
12  }
13
14  @wire(apexMethod, { theValues: "$objVal" })
15  propertyOrFunction;
16}

関連トピック

The Japanese Summer '24 guide is now live

日本語の Summer '24 ガイドが公開されました! 「Component Reference (コンポーネントリファレンス)」は、以前と同様にコンポーネントライブラリにあります。