' P '

whatever I will forget

LWCのデータアクセス

LWC/Visualforceとのデータアクセスの違い

  • LWC
    • ClientはJavaScriptからLDS(Lightning Data Service)、あるいはApexを呼び出す
    • LWCエンジンがクライアントにデータを返却し、JavaScriptがデータを保持してmarkupを生成する

LDS(Lightning Data Service)

  • Apexを使用せずとも、LDSのJavaScriptがレコードの参照、作成、編集を行ったり、metadataを参照することができる
  • LDSはキャッシュや同期をLWCに対して行える

LWCでのApexの使用

  • メソッドはStatelessにしなければいけない
    • staticメソッドにする必要がある
    • メソッドは必要なパラメータを全て渡す必要がある
    • メソッドはコンポーネント側で必要な全ての変数をreturnする必要がある
  • メソッドは@AuraEnabledである必要がある
public with sharing class AccountListControllerVisualforce {
    public List<Account> accounts { get; private set; }
    public Integer numberOfEmployees { get; set; }
    public void queryAccounts() {
        // In real world, probably more complex logic here
        this.accounts = [
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees = :numberOfEmployees
        ];
    }
}

↑ Visualforce用のApexコントローラー
↓ LWC用のApexコントローラー

public with sharing class AccountListControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Account> queryAccounts(Integer numberOfEmployees) {
        return [ // Return whatever the component needs
            SELECT Name
            FROM Account
            WHERE NumberOfEmployees >= :numberOfEmployees
        ];
    }
}

LWCからのApexのcall

  • JavaScriptからApex Methodをimportしないといけない
import queryAccounts from '@salesforce/apex/AccountListControllerLwc.queryAccounts';

RecordIdのアクセス方法

  • Visualforceの場合
public with sharing class AccountControllerVisualforce {
    public List<Contact> contacts { get; private set; }
    private ApexPages.StandardController standardController;
    public AccountController(ApexPages.StandardController standardController) {
        this.standardController = standardController;
        this.contacts = new List<Contact>();
    }
    public void queryRelatedContacts() {
        this.contacts = [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :standardController.getId() // (2)
        ];
   }
}

standardController.getId()にて現在参照しているレコードIdの取得が可能

<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

第一に、js-meta.xmlファイルでコンポーネントをexposeする

import { LightningElement, wire, api } from 'lwc';
import queryRelatedContacts from '@salesforce/apex/AccountControllerLwc.queryRelatedContacts';
export default class AccountInfo extends LightningElement {
    @api recordId;
    @wire(queryRelatedContacts, { accountId: '$recordId' })
    contacts;
}

@api recordIdをpublic propertyとして定義しておく。(@apiにてpublicにできる)
これにより親コンポーネントがこの値をセットする。
上記をApexメソッドに引数として渡す。

public with sharing class AccountControllerLwc {
    @AuraEnabled(cacheable=true)
    public static List<Contact> queryRelatedContacts(Id accountId) {
        return [
            SELECT Name, Title, Email, Phone
            FROM Contact
            WHERE AccountId = :accountId
        ];
    }
}

サーバーエラーについて

LWCではJavaScriptにてHandleさせる。
Visualforceではcatchの中にApexPages.addMessages(e);としていた。

try {
    // Perform logic that may throw an exception.
} catch (Exception e) {
    throw new MyCustomException('Records could not be retrieved at this time. Try again later');
}

キャッシュの設定

設定 → キャッシュの設定

このチェックをOFFにすると、キャッシュが消えるのを待つ必要性がなくなる。開発時に主に使用するかも。