salesforcelightning零基础学习lightningdataservice(lds)(代码片段)

zero-zyq zero-zyq     2022-12-27     462

关键词:

本篇可参看:https://trailhead.salesforce.com/modules/lightning_data_service

Lightning中针对object的detail页面,一个lightning app可能包含了多个components,多个components不可避免的会对这个数据进行CRUD操作,如果我们针对每个component都在init操作时后台SQL进行查询,然后赋值给前台变量,进行CUD操作时,还要考虑其他component的数据是否要级联的改变,这种操作以及设计对于性能的影响还是蛮大的,有什么好的方法可以做到一次搜索或者一次加载,所有的components都共用吗?这个时候,LDS或许可以是你想要的。

lightning中,我们使用 Lightning Data Service(LDS)去服务于数据层面,LDS 提供了对数据的访问。

LDS除了可以让一个app的所有的component共用一个share的数据,这样一个更新以后,所有的component(model 为view)都会同步的刷新这个数据。还可以支持用户离线操作数据,当网络连接以后,用户对数据的操作则会进行同步。

LDS优点概括来说:

最小化的XMLHttpRequests

数据只需要搜索一次。

跨 components 分享数据记录

当数据改变以后会创建通知。

优点还有很多,当一个app 涉及到记录的简单的增删改查操作,使用LDS是一个最优的方式。

说了这么多LDS的优点,那LDS如何使用呢?其实只需要在component中引入 <force:recordData>标签即可。

一. <force:recordData>属性介绍
<force:recordData>标签包含以下的常用属性:

recordId : 指定哪条记录来加载,此字段为必须字段。

mode: 指定当前的模式,有 View和Edit两个值。如果针对当前component有update操作,则mode设置为Edit。此字段为必须字段

layoutType: 决定了哪个layout用于加载, FULL/COMPACT。

fields: 决定哪些字段用来搜索出来

layoutType以及fields至少有一个要求必须,因为管理员拥有更改pagelayout的权限,所以layoutType加载的字段具有不确定性,推荐使用fields。

targetRecord: 此属性相当于这条记录ID对应的记录变量,通过此变量可以访问fields中指定的字段值。

targetFields: targetRecord对应的字段的视图,通过此字段可以取出fields中的指定的值。

通过上面的描述可以看出来targetRecord以及targetFields均可以取出fields中指定的字段值,他们两个写法尽管不同,但是他们的表达含义以及取得值相同,后面有具体的描述。

targetError: 此属性存储Error Message, 如果记录没有正确的提供。

recordUpdated:此属性指定当记录进行了CUD操作时的事件处理。

简单Demo如下:其中 v.accountFields.Name 等同于!v.record.fields.Name.

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
    <aura:attribute name="record" type="Object"/>
    <aura:attribute name="accountException" type="String"/>
    <aura:attribute name="accountFields" type="Object"/>
    <force:recordData
        recordId="!v.recordId"
        aura:id="accId"
        targetRecord="!v.record"
        targetFields="!v.accountFields"
                targetError="!v.accountException"
        fields="Id,Name,Industry"
        mode="VIEW"/>
    <lightning:card title="!v.accountFields.Name">
        <lightning:formattedText title="Industry" value="!v.record.fields.Industry"/>
    </lightning:card>
</aura:component>

 二. LDS的 CUD,错误提示以及自带的事件监听操作

force:recordData组件元素自带了好几个方法用来实现数据的简单的增删改操作。controller.js中通过获取到force:recordData元素后调用相关的方法即可进行DML操作。常用方法如下:

  • getNewRecord():创建一条新记录,通常用于insert操作,init handler中调用此方法创建一条ID为空的记录,此方法不会返回任何类型的callback function;
  •  saveRecord(): 用于 insert/update记录,此方法会返回一个 SaveRecordResult对象的callback function,SaveResult后面会详细介绍;
  •  deleteRecord():用于记录的delete操作,此方法会返回一个SaveRecordResult对象的callback function。

通过上面的常用的三个方法,我们会关注到SaveRecordResult这个对象,此类作为CUD操作的callback返回的唯一参数,此对象具有以下的字段:

  • objectApiName:当前操作的object的 API name;
  • entityLabel: 当前操作的object的label name;
  • error: 如果发生系统或者自定义的操作此记录的错误,则返回在error字段里面,此error字段返回的类型为list,可以通过for循环迭代出所有的错误信息。如果当前的操作状态为操作成功(save state为success或者draft)则error为undefined;
  • recordId: 当前操作记录的18位的ID;
  • state: 返回当前操作的结果状态: SUCCESS(操作成功)/ DRAFT(Server不可达,本地存储成功)/ INCOMPLETE(Server不可达,本地不支持存储)/ERROR(存储错误,由于validation或者其他的原因)。

getNewRecord():此方法用于创建一个空的记录,方法有四个参数:

  • objectApiName: 需要创建的 object 的API name;
  • recordTypeId:  需要创建的object的record type 的ID,如果没有指定,默认为default record type;
  • skipCache:判断是否从server端获取object的template还是从客户端获取;
  • callback:当object创建完以后的回调函数,此函数没有任何参数,创建完成以后会自动调用此方法。

saveRecord():此方法用于create/edit操作,方法只有一个参数:

  • callback:当object create/update完成以后的回调函数,次函数也包含了一个参数,即上面提到的SaveResultResult对象的变量引用。

deleteRecord():此方法用于delete操作,方法也只有一个参数:

  • callback:当object delete完成以后的回调函数,次函数也包含了一个参数,即上面提到的SaveResultResult对象的变量引用。

上面说过,通过LDS可以在数据变化后,共用的component实时的刷新数据,但是当两个同样的字段同时在Edit 模式下,则不会同时刷新,即刷新数据仅限于View模式下。

 举个例子:Account 新增一个 Action,用来展示和更新Account的部分字段信息。

1). accDisplay.cmp : 用来展示主要的几个字段

 1 <aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
 2     <aura:attribute name="record" type="Object"/>
 3     <aura:attribute name="accountException" type="String"/>
 4     <aura:attribute name="recordFields" type="Object"/>
 5     <force:recordData
 6         recordId="!v.recordId"
 7         aura:id="accId"
 8         targetRecord="!v.record"
 9         targetFields="!v.recordFields"
10         fields="Name,AccountNumber,Site"
11         mode="VIEW"
12         />
13     <lightning:card title="Acc View" iconName="action:info">
14         <lightning:formattedText title="Name" value="!v.recordFields.Name"/>
15         <br/>
16         <lightning:formattedText title="Account Number" value="!v.recordFields.AccountNumber"/>
17         <br/>
18         <lightning:formattedText title="Site" value="!v.recordFields.Site"/>
19         <br/>
20 
21     </lightning:card>
22 </aura:component>

2). accEdit2.cmp:更新固定的几个字段

 1 <aura:component implements="force:hasRecordId, 
 2                             force:lightningQuickActionWithoutHeader">
 3     <aura:attribute name="record" 
 4                     type="Object" description="current record reference"/>
 5     <aura:attribute name="recordFields" 
 6                     type="Object" description="current record fields list"/>
 7     <aura:attribute name="recordError"
 8                     type="String" description="if error occurs,record error reference"/>
 9     
10     <force:recordData aura:id="editRecordId"
11                       fields="Name,AccountNumber,Site"
12                       recordId="!v.recordId"
13                       targetError="!v.recordError"
14                       targetRecord="!v.record"
15                       targetFields="!v.recordFields"
16                       mode="EDIT"
17                       />
18     
19     <!-- Display an editing form -->
20     <div class="Edit Account Details">
21         <lightning:card iconName="action:edit" title="!v.recordFields.Name">
22             <div class="slds-p-horizontal--small">
23 
24                 <lightning:input label="Name" 
25                                  value="!v.recordFields.Name"/>
26                 <br/>
27                 <lightning:input label="Account Number" 
28                                  value="!v.recordFields.AccountNumber"/>
29                 <br/>
30                 <lightning:input label="Site" 
31                                  value="!v.recordFields.Site"/>
32                 <br/>
33 
34                 <lightning:button label="Save" 
35                                   variant="brand" 
36                                   onclick="!c.handleSaveRecord"/>
37             </div>
38         </lightning:card>
39     </div>
40     
41     <!-- if error occurs, display operate error -->
42     <aura:if isTrue="!not(empty(v.recordError))">
43         <div class="recordError">
44             !v.recordError
45         </div>
46     </aura:if>
47 </aura:component>

 

3). AccComponent.cmp: 通过Tab方式展示数据信息,因为想要测试一个场景,所以此component里面引用了两遍accEdit2.cmp

 1 <aura:component implements="flexipage:availableForAllPageTypes,force:lightningQuickAction,force:hasRecordId">
 2     <lightning:tabSet class="slds-tabs_scoped">
 3         <lightning:tab label="Acc View">
 4             <c:AccDisplay recordId="!v.recordId"/>
 5         </lightning:tab>
 6         <lightning:tab label="Acc Edit">
 7             <c:AccEdit2 recordId="!v.recordId"/>
 8         </lightning:tab>
 9         <lightning:tab label="Acc Edit2">
10             <c:AccEdit2 recordId="!v.recordId"/>
11         </lightning:tab>
12     </lightning:tabSet>
13 </aura:component>

 4). 新建一个Lightning Action,并且将此Action放在Page Layout中

技术分享图片

结果展示:

 1.点击Edit Test会弹出Pop Up Window

技术分享图片

2.在ACC EDIT Tab输入了内容点击Save以后,结果展示位ACC View的Tab会立刻显示输入后save的内容,而ACC Edit2 Tab则会保留原值。

技术分享图片

 通过结果可以看出来,在mode为view情况下,save以后会立刻显示在view视图中。在mode为Edit情况下,如果edit1有某个字段更新,比如Account Number,则edit2的Account Number不会被更新。这种设计也是正常的,因为如果同步更新会有歧义,但是我们有一些场景还是希望Edit模式下也可以自动更新这些值得,这个时候就可以使用到自带的事件监听。

 自带事件监听使用非常简单,只需要<force:recordData>标签增加属性:recordUpdated属性设置你需要后台controller绑定的handler即可。

使用LDS的事件监听有4中类型: CHANGED / LOADED / REMOVED / ERROR。 从名字可以看出来分别对应着 更改 / 加载 / 移除 / 错误。

下面我们针对上面的程序进行改进,对accEdit2.cmp 优化一下force:recordData组件元素

1 <force:recordData aura:id="editRecord2Id"
2                       fields="Name,AccountNumber,Site"
3                       recordId="!v.recordId"
4                       targetError="!v.recordError"
5                       targetRecord="!v.record"
6                       targetFields="!v.recordFields"
7                       mode="EDIT"
8                       recordUpdated="!c.reloadUpdate"
9                       />

对accEdit2Controller.js增加一个reloadUpdate方法,其中调用reloadRecord()方法可以对force:recordData进行重新数据加载。

 1 reloadUpdate : function(component, event, helper) 
 2         var eventParams = event.getParams();
 3         if(eventParams.changeType == "CHANGED") 
 4             // get the changed fields for this record
 5             var changedFields = eventParams.changedFields;
 6             console.log(‘Chaged Fields: ‘ + JSON.stringify(changedFields));
 7             component.find(‘editRecordId‘).reloadRecord();
 8          else if(eventParams.changeType === "LOADED") 
 9             console.log("Record is loaded successfully.");
10          else if(eventParams.changeType === "REMOVED") 
11             var deleteRecordResult = $A.get("e.force:showToast");
12             deleteRecordResult.setParams(
13                 "title": "Delete Result",
14                 "message": "The record was deleted."
15             );
16             deleteRecordResult.fire();
17          else if(eventParams.changeType === "ERROR") 
18             console.log(‘Error: ‘ + component.get("v.error"));
19         
20 

增强上述方法以后,在重新运行,当ACC Edit Tab中改了相关的值以后,ACC Edit2 Tab的值也会同步的更新,因为LDS已经加载成了最新的值。

(注意:调用reloadRecord()方法以后,会重新执行事件类型为LOADED的事件设置,demo中如果save以后会打出Record is loaded successfully.)

总结:使用LDS可以在不使用controller情况下便进行简单的CUD操作,很类似classic 中的standcontroller功能。这种方式在lightning中还是很常见的,但是如果涉及到复杂的数据关联的改动或者transaction中需要进行多次更新操作,建议不使用LDS换成后台controller中去做。篇中只弄了Edit的demo,new以及delete的demo感兴趣的可以自己去玩。篇中有错误的欢迎指出,有问题欢迎留言。


salesforcelightning零基础学习lightning简单介绍以及org开启lightning

lightning对于开发salesforce人员来说并不陌生,即使没有做过lightning开发,这个名字肯定也是耳熟能详。原来的博客基本都是基于classic基于配置以及开发,后期博客会以lightning为主。那么问题来了,whylightning?lightning针对classic,不... 查看详情

salesforcelightning零基础学习列表展示数据时两种自定义编辑页面(代码片段)

上一篇Lightning内容描述的是LDS,通过LDS可以很方便的实例化一个对象的数据信息。当我们通过列表展示数据需要编辑时,我们常使用两种方式去处理编辑页面:PopUpWindow弹出修改详情以及在本页面隐藏详情页面显示编辑页面。&nbs... 查看详情

salesforcelightning零基础学习表达式的!(绑定表达式)与#(非绑定表达式)(代码片段)

在salesforce的classic中,我们使用!expresion在前台页面展示信息,在lightning中,上一篇我们也提及了,如果展示attribute的值,可以使用!v.expresion展示信息。lightning在component中解析动态值的时候,会将!这个里面的变量进行动态的解析... 查看详情

salesforcelightning零基础学习(十三)自定义lookup组件(single&multiple)(代码片段)

上一篇简单的介绍了自定义的Lookup单选的组件,功能为通过引用组件Attribute传递相关的sObjectName,捕捉用户输入的信息,从而实现搜索的功能。我们做项目的时候,可能要从多个表中获取数据并且选择相关的记录(单选或者多选... 查看详情

零基础学习js——基础续

while语句每次执行完语句块之后,又会跳回去检查小括号()里面的布尔值,如果为true,即再执行语句块。     while(true){console.log(‘true‘)}       //求1+2+3+...+100=?的值vari=1;vars=0;while(i&l 查看详情

trailhead莱特宁学习一(代码片段)

...,以下是查阅的资料。简介在此Salesforce教程中,将阐述SalesforceLightning的基础知识,并了解SalesforceLightning的重要性。让我们看看什么是CRM,什么使Salesforce发挥作用?CRM代表客户关系管理,客户关系管理是一种工具,公司可以通... 查看详情

零基础入门深度学习-卷积神经网络(代码片段)

前向传播:eginalignotagx_j^l=f(sum_iinM_jx_i^l-1*k_ij^l+b_j^l)endaligndefforward(self,input_array):'''计算卷积层的输出输出结果保存在self.output_array'''self.input_array=input_arrayself.padded_input_array=padding(input_array,self.zero_padding)forfinrange(s... 查看详情

转载零基础入门深度学习-参考文献

【转载】零基础入门深度学习-参考文献机器学习深度学习参考资料零基础入门深度学习(1)-感知器TomM.Mitchell,“机器学习”,曾华军等译,机械工业出版社零基础入门深度学习(2)-线性单元和梯度下降TomM.Mitchell,“机器学习”,曾华军... 查看详情

转载零基础入门深度学习-参考文献

【转载】零基础入门深度学习-参考文献机器学习深度学习参考资料零基础入门深度学习(1)-感知器TomM.Mitchell,“机器学习”,曾华军等译,机械工业出版社零基础入门深度学习(2)-线性单元和梯度下降TomM.Mitchell,“机器学习”,曾华军... 查看详情

零基础如何学习java

...做计算机,可是又不知道从何入手,我建议大家可以从零基础学习java开始。刚开始学习java,我建议大家从视频学习入手,前期先打好基础,我看到一个淘宝店上有一个零基础java学习视频,里面内容挺详细的,非常的零基础,我... 查看详情

零基础入门深度学习目录

...专栏:《深度学习100例》🔥推荐专栏:《零基础入门深度学习》📚选自专栏:《Matplotlib教程》🧿优秀专栏:《Python入门100题》📕入门篇1.环境配置【零基础入门深度学习】1-1:配置深度学习... 查看详情

学习资料

一、深度学习1、https://www.zybuluo.com/hanbingtao/note/433855零基础入门深度学习(1)-感知器 零基础入门深度学习(2)-线性单元和梯度下降 零基础入门深度学习(3)-神经网络和反向传播算法 零基础入门深度学习(4)-卷积神经网络&nb... 查看详情

零基础学习web前端开发:html第一部分基础知识的综合案例

零基础学习WEB前端开发(一):网站及web标准简介零基础学习WEB前端开发(二):HTML标签及开发工具零基础学习WEB前端开发(三):VsCode工具生成的代码框架分析零基础学习WEB前端开发(四):HTML文本编辑标签及分块标签零... 查看详情

转载零基础入门深度学习-感知器(代码片段)

【转载】零基础入门深度学习(1)-感知器机器学习深度学习转载自https://www.zybuluo.com/hanbingtao/note/433855无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理... 查看详情

经验分享零基础python学习路线及阶段学习目标

零基础Python学习路线及阶段学习目标,首先应该夯实Python核心基础、Web前端编程、Django开发框架、Flask开发框架、爬虫与数据分析等知识,理解机器学习相关的基本概念及系统处理流程。 零基础Python学习路线及阶段学习... 查看详情

零基础深度学习能学明白吗?

作为成年人零基础深度学习,学习效果还是很好的,毕竟人们理解能力强了很多,更能踏实下来潜心学习。是可以学会的。参考技术A虽然没有基础,但只要你认真学习,就一定会有收获的。而且深度学习可以大大提高你的学习... 查看详情

零基础学习canoepanel(17)——panelcaplfunction

查看详情

java培训分享:零基础怎么学习java?

最近几年,有很多小伙伴都比较关注“零基础怎么学习Java?”这个问题,因为很多小伙伴都是从其他行业转型来学Java的,都很担心自己学不会,那么来看看下面的详细介绍吧。零基础怎么学习Java?来看看以下才几... 查看详情