レコードの変更およびエラーの処理
学習の目的
この単元を完了すると、次のことができるようになります。
- 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:recordData
のtargetRecord
属性とtargetFields
属性を新しいレコード値に設定します。UI でtargetRecord
またはtargetFields
を参照している場合、これにより再表示が自動的に起動されるため、UI に最新のデータが表示されます。
サーバで行われた変更を LDS で検出するときは、同じ変更通知メカニズムを使用します。LDS は、新しいレコード要求を受信したときに、サーバでの変更を検出します。LDS は、isValid
として登録されそのフラグが設定されているコンポーネントにのみ通知します。recordUpdated
イベントを処理するときは、changeType
を確認し、処理する変更の種類があるかどうかを探します。
エラー処理
読み込み中にエラーが発生した場合、targetError
属性は、ローカライズされたエラーメッセージに設定されます。エラーが発生するのは、force:recordData
内の属性が無効な場合、またはサーバにアクセスできず、レコードがローカルキャッシュにない場合です。ここからエラーをどのように表示するかは、あなた次第です。
サーバ上でレコードがアクセス不能になると、changeType
= REMOVED
で recordUpdated
イベントが起動されます。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
を使用します。
<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
イベントも処理するので、編集の結果に応じて特定のアクションを実行できます。
<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>
最後にコントローラを使用して、編集の結果に応じて、成功した編集をトーストメッセージで報告したり、エラーメッセージを表示したりします。
({ 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 コンポーネントのパフォーマンスと一貫性の向上を図ってください。