学习目标
完成本单元后,您将能够:
- 解释Lightning Data Service如何使用通知。
- 使用recordUpdated来处理错误并记录更改。
记录更改
在最后一个单元中,我们介绍了Lightning Data Service如何处理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}" />
({
recordUpdated: function(component, event, helper) {
var eventParams = event.getParams();
if(eventParams.changeType === "CHANGED") {
// 获取为此记录更改的字段
var changedFields = eventParams.changedFields;
console.log('Fields that are changed: ' + JSON.stringify(changedFields));
// 记录被改变,所以刷新组件(或其他组件逻辑)
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通过使用适当的changeType和changedFields值触发recordUpdated事件来通知所有其他的force的实例:recordData。
- 它将每个force:recordData上的targetRecord和targetFields属性设置为新的记录值。如果targetRecord或targetFields被任何UI引用,则会自动触发重新渲染,以便UI显示最新的数据。
错误处理
如果加载时发生错误,则将targetError属性设置为本地化的错误消息。如果强制属性:recordData无效,或者服务器不可访问且记录不在本地缓存中,则会发生错误。从那里,你决定如何显示错误。
如果记录在服务器上无法访问,那么recordUpdated事件触发changeType = REMOVED,并且没有错误设置为targetError,因为记录变得不可访问有时是预期的结果。由于记录或实体共享和可见性设置,或记录被删除,记录也可能变得不可访问。
把它放在一起
恭喜!现在您已经知道开始使用Lightning Data Service所需了解的一切。这是相对简单的,但它做了很多!在你脱颖而出并获得那个新奇的徽章之前,让我们把所有这些理论付诸实践。我们将放置一个页面,其中包含两个使用相同记录数据的组件,并正确响应记录更改。
该组件显示联系人的详细信息。请注意,它使用字段而不是layoutType,targetFields而不是targetRecord。请记住,可以包含fields或layoutType(或两者!),并且可以使用targetFields或targetRecord(或两者!)来检索记录数据。对于字段,您必须指定要查询的特定字段,而使用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,Industry"
targetFields="{!v.contactRecord}"
targetError="{!v.recordLoadError}"
/>
<!-- 显示有关联系人详情的闪电卡 -->
<div class="Contact Details">
<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>
<p class="slds-text-heading--small">
<lightning:formattedText title="Industry" value="{!v.contactRecord.Industry}" /></p>
</div>
</lightning:card>
</div>
</aura:component>
<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,Industry"
targetFields="{!v.contactRecord}"
targetError="{!v.recordSaveError}"
mode="EDIT"
recordUpdated="{!c.handleRecordUpdated}" />
<!-- Contact edit form -->
<div class="Edit Contact">
<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>
</div>
<!-- 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是一个错误数组,
// 将所有错误收集到一个消息中
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", "");
}
}));
},
// 在更改记录时(通过任何组件),在这里控制组件行为
handleRecordUpdated: function(component, event, helper) {
var eventParams = event.getParams();
if(eventParams.changeType === "CHANGED") {
// 获取为此记录更改的字段
var changedFields = eventParams.changedFields;
console.log('Fields that are changed: ' + JSON.stringify(changedFields));
// 记录被改变,所以刷新组件(或其他组件逻辑)
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"));
}
}
})