レコードの変更およびエラーの処理

学習の目的

この単元を完了すると、次のことができるようになります。

  • Aura コンポーネントのための Lightning データサービスで通知を使用する方法を説明する。
  • recordUpdated を使用して、エラーとレコードの変更を処理する。

レコードの変更

前の単元では、Lightning データサービスで CRUD を処理する方法について説明しました。ここでは、レコードの変更時にアクションを実行する方法を見ていきます。これにより、コンポーネントでレコードの読み込み、変更、更新、または削除に応答できます。

レコードの変更時にアクションを実行するには、recordUpdated イベントを処理します。

<force:recordData aura:id="forceRecordDataCmp"
    recordId="{!v.recordId}"
    layoutType="{!v.layout}"
    targetRecord="{!v.record}"
    targetFields="{!v.simpleRecord}"
    targetError="{!v.error}"
    recordUpdated="{!c.recordUpdated}" />

変更を処理するアクションハンドラを実装します。項目の変更は changedFields オブジェクトを通じて渡されます。このオブジェクトには、新しい値に関連する古い項目値が含まれます。

({
    recordUpdated: function(component, event, helper) {
        var eventParams = event.getParams();
        if(eventParams.changeType === "CHANGED") {
            // get the fields that are changed for this record
            var changedFields = eventParams.changedFields;
            console.log('Fields that are changed: ' + JSON.stringify(changedFields));
            // record is changed so refresh the component (or other component logic)
            var resultsToast = $A.get("e.force:showToast");
            resultsToast.setParams({
                "title": "Saved",
                "message": "The record was updated."
            });
            resultsToast.fire();
        } else if(eventParams.changeType === "LOADED") {
            console.log("Record is loaded successfully.");
        } else if(eventParams.changeType === "REMOVED") {
            var resultsToast = $A.get("e.force:showToast");
            resultsToast.setParams({
                "title": "Deleted",
                "message": "The record was deleted."
            });
            resultsToast.fire();
        } else if(eventParams.changeType === "ERROR") {
            console.log('Error: ' + component.get("v.error"));
        }
    }
})

LDS がレコードの変更を検出すると、そのレコードを使用するコンポーネントに変更が通知されます。変更に対する処理を行わなくても、レコードは更新されます。そのため、targetRecord または targetFields プロパティへの参照があれば、それらはコンポーネントに自動的に表示されます。更新されたレコードを参照する force:recordData コンポーネントごとに、LDS は 2 つの処理を行います。

  • LDS は、適切な changeType 値と changedFields 値を使用して recordUpdated イベントを起動することで、force:recordData の他のすべてのインスタンスに変更を通知します。
  • force:recordDatatargetRecord 属性と targetFields 属性を新しいレコード値に設定します。UI で targetRecord または targetFields を参照している場合、これにより再表示が自動的に起動されるため、UI に最新のデータが表示されます。
メモ

メモ

force:recordData が EDIT モードになっている場合、レコードが変更されても targetRecordtargetFields は自動的に更新されません。これは、進行中の編集内容が誤って上書きされて失われないようにすること、および未保存の変更が他のコンポーネントに表示されないようにすることを目的とします。心配はいりません。recordUpdated イベントを処理し、reloadRecord メソッドをコールすることで、レコードを手動で更新できます。

サーバで行われた変更を LDS で検出するときは、同じ変更通知メカニズムを使用します。LDS は、新しいレコード要求を受信したときに、サーバでの変更を検出します。LDS は、isValid として登録されそのフラグが設定されているコンポーネントにのみ通知します。recordUpdated イベントを処理するときは、changeType を確認し、処理する変更の種類があるかどうかを探します。

エラー処理

読み込み中にエラーが発生した場合、targetError 属性は、ローカライズされたエラーメッセージに設定されます。エラーが発生するのは、force:recordData 内の属性が無効な場合、またはサーバにアクセスできず、レコードがローカルキャッシュにない場合です。ここからエラーをどのように表示するかは、あなた次第です。

サーバ上でレコードがアクセス不能になると、changeType = REMOVEDrecordUpdated イベントが起動されます。targetError にエラーは設定されません。レコードがアクセス不能になることが、期待される結果の場合があるためです。レコードは、レコードまたはエンティティの共有および表示設定により、あるいは、レコードが削除されていることによりアクセス不能になることもあります。

すべてを総合

おめでとうございます。Lightning データサービスの使用を開始するにあたって知っておくべきすべての情報を得ました。これは比較的に簡単ですが、多くの機能があります。修了し、洒落た新しいバッジを獲得する前に、すべての理論を実践してみましょう。同じレコードデータを使用する 2 つのコンポーネントが含まれるページをまとめて、レコードの変更に適切に対応します。

このコンポーネントには取引先責任者の詳細が表示されます。これは、layoutType の代わりに fields を使用し、targetRecord ではなく targetFields を使用します。fields または layoutType のどちらか (あるいは両方) を含めることができること、および targetFields または targetRecord のどちらか (あるいは両方) を使用してレコードデータを取得できることを思い出してください。fields を使用する場合は、照会する特定の項目を指定する必要がありますが、layoutType を使用する場合は、使用するレコードレイアウト (FULL または COMPACT) を指定するだけで済みます。targetFields を使用してデータを取得する場合 (この方法をお勧めします)、UI で v.targetFields.Name の形式を使用します。targetRecord を使用している場合は、v.targetRecord.fields.Name.value を使用します。

ldsShowContact.cmp
<aura:component implements="force:hasRecordId,flexipage:availableForRecordHome">
    <aura:attribute name="contactRecord" type="Object"/>
    <aura:attribute name="recordLoadError" type="String"/>
    <force:recordData aura:id="recordLoader"
        recordId="{!v.recordId}"
        fields="Name,Description,Phone"
        targetFields="{!v.contactRecord}"
        targetError="{!v.recordLoadError}"
    />
    <!-- Display a lightning card with details about the contact -->
    <lightning:card iconName="standard:contact" title="{!v.contactRecord.Name}" >
        <div class="slds-p-horizontal--small">
            <p class="slds-text-heading--small">
                <lightning:formattedPhone title="Phone"  value="{!v.contactRecord.Phone}" /></p>
            <p class="slds-text-heading--small">
                <lightning:formattedText title="Description" value="{!v.contactRecord.Description}" /></p>
        </div>
    </lightning:card>
</aura:component>

次のコンポーネントは同じ取引先責任者を読み込みますが、EDIT モードでは、1 つのフォームと共に取引先責任者を読み込みます。ユーザはこのフォームを使用して取引先責任者自体を編集できます。また、これは recordUpdated イベントも処理するので、編集の結果に応じて特定のアクションを実行できます。

ldsEditContact.cmp
<aura:component implements="force:hasRecordId,flexipage:availableForRecordHome">
    <aura:attribute name="contactRecord" type="Object"/>
    <aura:attribute name="recordSaveError" type="String" default=""/>
    <!-- Load record in EDIT mode -->
    <force:recordData aura:id="recordLoader"
        recordId="{!v.recordId}"
        fields="Name,Description,Phone"
        targetFields="{!v.contactRecord}"
        targetError="{!v.recordSaveError}"
        mode="EDIT"
        recordUpdated="{!c.handleRecordUpdated}" />
    <!-- Contact edit form -->
    <lightning:card iconName="action:edit" title="Edit Contact">
        <div class="slds-p-horizontal--small">
            <lightning:input label="Contact Name" value="{!v.contactRecord.Name}"/>
            <lightning:input label="Contact Description" value="{!v.contactRecord.Description}"/>
            <lightning:input label="Contact Phone" value="{!v.contactRecord.Phone}"/>
            <br/>
            <lightning:button label="Save Contact" variant="brand" onclick="{!c.saveContact}" />
        </div>
    </lightning:card>
    <!-- Display error message -->
    <aura:if isTrue="{!not(empty(v.recordSaveError))}">
        <div class="recordSaveError">
            {!v.recordSaveError}</div>
    </aura:if>
</aura:component>

最後にコントローラを使用して、編集の結果に応じて、成功した編集をトーストメッセージで報告したり、エラーメッセージを表示したりします。

ldsEditContactController.js
({
    saveContact : function(cmp, event, helper) {
        var recordLoader = cmp.find("recordLoader");
        recordLoader.saveRecord($A.getCallback(function(saveResult) {
            if (saveResult.state === "ERROR") {
                var errMsg = "";
                // saveResult.error is an array of errors,
                // so collect all errors into one message
                for (var i = 0; i < saveResult.error.length; i++) {
                    errMsg += saveResult.error[i].message + "\n";
                }
                cmp.set("v.recordSaveError", errMsg);
            } else {
                cmp.set("v.recordSaveError", "");
            }
        }));
    },
    // Control the component behavior here when record is changed (via any component)
    handleRecordUpdated: function(component, event, helper) {
        var eventParams = event.getParams();
        if(eventParams.changeType === "CHANGED") {
            // get the fields that are changed for this record
            var changedFields = eventParams.changedFields;
            console.log('Fields that are changed: ' + JSON.stringify(changedFields));
            // record is changed so refresh the component (or other component logic)
            var resultsToast = $A.get("e.force:showToast");
            resultsToast.setParams({
                "title": "Saved",
                "message": "The record was updated."
            });
            resultsToast.fire();
        } else if(eventParams.changeType === "LOADED") {
            // record is loaded in the cache
        } else if(eventParams.changeType === "REMOVED") {
            // record is deleted and removed from the cache
        } else if(eventParams.changeType === "ERROR") {
            console.log('Error: ' + component.get("v.error"));
        }
    }
})

これであなたは Lightning データサービスの名人です。新しく身につけたスキルを使用して、Trailblazer のあらゆる場所で Lightning コンポーネントのパフォーマンスと一貫性の向上を図ってください。

リソース

無料で学習を続けましょう!
続けるにはアカウントにサインアップしてください。
サインアップすると次のような機能が利用できるようになります。
  • 各自のキャリア目標に合わせてパーソナライズされたおすすめが表示される
  • ハンズオン Challenge やテストでスキルを練習できる
  • 進捗状況を追跡して上司と共有できる
  • メンターやキャリアチャンスと繋がることができる