2018.02.19

Lightning Data Service を使ってみよう!

  • このエントリーをはてなブックマークに追加
  • follow us in feedly
みなさま、こんにちは。
テラスカイ西日本の張です。

Lightning Data Service(LDS)がSalesforce Winter '18 に正式リリースされました。開発者としては待ち遠しい技術ではないかと思います。
LDSを使うと、ApexコードなしでレコードのCRUD操作を実行できるLinghtning コンポーネントを素早く作成できます。Visualforceの開発でよく利用される「標準コントローラ」を思い出してください。LDSは、Visualforce 標準コントローラの Lightning コンポーネントバージョンと考えても良いでしょう。

LDS利用前後のLightningコンポーネントの構成

LDSを使わない場合、各LightningコンポーネントがApexコントローラとやり取りして、サーバの負荷が増える一方、同一画面にあるコンポーネント間のデータの整合性を取るのに工夫が必要になります。

LDSを使う場合、サーバとの通信はLDSより管理され、コンポーネントの数に関係なく、同じレコードへのアクセスであれば、検索回数が減らされるため、パフォーマンスは大幅に改善されます。更にローカルストレージを使ってレコードはキャッシュされ、コンポーネント間で共有されます。レコードがあるコンポーネントによって更新された場合、すべてのコンポーネントに通知され、画面表示も自動的に更新されます。

LDSのメリット

  • レコードを1回読み込むとすべてのコンポーネントに反映できるため、ネットワーク通信とサーバ負荷を軽減できます
  • クライアント側キャッシュを使って、複数コンポーネント間のデータが共有され、データの整合性が向上します
  • あるコンポーネントよりレコードが変更されるとほかのコンポーネントに自動的に通知できます
  • 項目へのアクセス権限は自動的にチェックされ、項目レベルセキュリティを確保できます
  • getNewRecord 関数や、saveRecord 関数などが既に用意されており、Apexコード無しでCRUD処理を実装できます

LDSの機能概要

LDSは下記の機能を備えています。
force:recordData タグ LDSを利用するためのコンポーネント
getNewRecord 関数 空のレコードを作成します
saveRecord 関数 レコードを保存します
deleteRecord 関数 レコードを削除します
recordUpdated イベント レコードが変更されたときに起動したイベント
changeType イベントパラメータ recordUpdated イベントのパラメータ
記述方法を簡単に説明します。
<force:recordData aura:id="recordSelect"
                  recordId="{!v.recordId}"
                   layoutType="FULL"
                   fields="{!v.fieldsToQuery}"
                   mode="VIEW"
                   targetRecord="{!v.record}"
                   targetFields="{!v.simpleRecord}"
                   targetError="{!v.recordError}"
                   recordUpdated="{!c.recordUpdated}" />
force:recordData
recordId:読込対象レコードのID
layoutType:FULL、またはCOMPACT
FULL:レコードのページレイアウト (レコードタイプのページレイアウト)
COMPACT:コンパクトレイアウト
fields :クエリするレコードの項目
(layoutType または fields 属性の指定は必須です)
mode:レコードを読み込むモード: VIEW (デフォルト) または EDIT
targetRecord – where to store the result
targetFields – 読み込んだレコードの項目を参照するための簡易ビュー
targetError :エラーメッセージ
ecordUpdated:レコードが変更されたときに起動するコントローラのメソッド

LDSの実装例

LDSを使って取引先のデータを簡単に変更できるコンポーネントを作ります。
画面で動作確認するため、Lightning コンポーネントのクイックアクションも作成します。

ステップ1.取引先データ表示用コンポーネントを作成

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" >
    <aura:attribute name="recordError" type="String"/>
    <aura:attribute name="recordInfo" type="Object" />
    <aura:attribute name="simpleRecord" type="Object"/>
    <aura:attribute name="recordId" type="String"/>
    <aura:attribute name="showEdit" type="Boolean"/>        
    <force:recordData aura:id="recordLoader"
                      recordId="{!v.recordId}"
                      layoutType="FULL"
                      mode="VIEW"
                      targetRecord="{!v.recordInfo}"                        
                      targetFields="{!v.simpleRecord}"    
                      targetError="{!v.recordError}"
                      />
    
    <div class="slds-form--stacked">
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="recordName">取引先名</label>
            <div class="slds-form-element__control">
                <lightning:formattedText title="取引先名"  value="{!v.simpleRecord.Name}" />
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="recordOwnerName">電話</label>
            <div class="slds-form-element__control">
                <lightning:formattedPhone title="電話"  value="{!v.simpleRecord.Phone}" />
            </div>
        </div>
        <div class="slds-form-element">
            <label class="slds-form-element__label" for="recordOwnerName">取引先 部門</label>
            <div class="slds-form-element__control">
                <lightning:formattedPhone title="取引先 部門"  value="{!v.simpleRecord.Site}" />
            </div>
        </div>
        <div class="slds-form-element slds-m-top--large">
            <lightning:button label="編集"  onclick="{!c.editAcc}"/>
        </div>
    </div>

    <!-- エラーメッセージ -->
    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError">
            {!v.recordSaveError}</div>
    </aura:if>
</aura:component>

LdsAccountShowController.js

({
    editAcc : function(component, event, helper) {
        component.set("v.showEdit", true);
    }
})
LdsAccountShow.cmp

ステップ2.取引先データ編集用コンポーネントを作成

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction" access="global" >
    <aura:attribute name="recordError" type="String"/>
    <aura:attribute name="recordInfo" type="Object" />
    <aura:attribute name="simpleRecord" type="Object"/>
    <aura:attribute name="showEdit" type="Boolean"/>            
    <force:recordData aura:id="recordHandler"
                      recordId="{!v.recordId}"
                      layoutType="FULL"
                      mode="EDIT"
                      targetRecord="{!v.recordInfo}"  
                      targetFields="{!v.simpleRecord}"
                      />
    <div class="slds-form--stacked"> 
        <div class="slds-form-element">
            <lightning:input label="取引先名" value="{!v.simpleRecord.Name}"/>
        </div>
        <div class="slds-form-element">
            <lightning:input label="電話" value="{!v.simpleRecord.Phone}"/>
        </div>
        <div class="slds-form-element">
            
            <lightning:input label="取引先 部門" value="{!v.simpleRecord.Site}"/>
        </div>
        <div class="slds-form-element slds-m-top--large">
            <lightning:button variant="brand" label="保存"  onclick="{!c.saveAcc}"/>
            <lightning:button label="キャンセル"  onclick="{!c.cancelSaveAcc}"/>
        </div> 
    </div>

    <!-- エラーメッセージ -->
    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError">
            {!v.recordError}</div>
    </aura:if>
    
</aura:component>

LdsAccountEditController.js

({
    saveAcc : function(component, event, helper) {
        component.find("recordHandler").saveRecord($A.getCallback(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                component.set("v.showEdit", false);
            } else {
                var errMsg = "";
                for (var i = 0; i < saveResult.error.length; i++) {
                    errMsg += saveResult.error[i].message + "\n";
                }
                cmp.set("v.recordError", errMsg);
            }
        }));
    },

    cancelSaveAcc : function(component, event, helper){
        component.set("v.showEdit", false);
    }
})
LdsAccountEdit.cmp

ステップ3.コンテナコンポーネントを作成

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickActionWithoutHeader" access="global" >
    <aura:attribute name="showEdit" type="Boolean" default="false" />
    
    <aura:if isTrue="{!v.showEdit == false}">
        <c:LdsAccountShow recordId="{!v.recordId}" showEdit="{!v.showEdit}" />
        <aura:set attribute="else">
            <c:LdsAccountEdit recordId="{!v.recordId}" showEdit="{!v.showEdit}" />
        </aura:set>
    </aura:if>
</aura:component>
LdsAccountContainer.cmp

ステップ4.Lightningコンポーネントクイックアクションを登録

ステップ5.動作確認

LDS利用時の考慮事項

Lightningデータサービスは、Lightning Experience と Salesforce1しか利用できません。DML処理対象は1レコードのみで、複数レコードを対象としてバルク処理はできません。すべてのオブジェクトには対応していません。利用可能オブジェクトはこちら(https://developer.salesforce.com/docs/atlas.ja-jp.210.0.lightning.meta/lightning/data_service_considerations.htm)に記載してあります。
LDSを使えば開発者はApexやSOQLを書かなくても、数行のコードでCRUD処理を簡単に実装できます。プログラムの構成も簡単になるため、開発コストも削減できるではないかと思います。興味のある方はぜひ試してみてください。
29 件

関連する記事