Salesforce LWC学习(六) @salesforce & lightning/ui*Api Reference

上一篇中咱们在demo中使用了不少的 @salesforce 以及 lightning/ui*Api的方法,可是不少没有细节的展开。其实LWC中针对这些module提供了不少好用的方法,下面对这两种进行详细介绍。javascript

一. @Salesforcehtml

@salesforce模块封装了不少的方法,用于在运行时添加相关的功能。主要方法及使用以下。java

1. @salesforce/apex : 此方法用于引入apex的方法,这里的方法包括自定义的方法以及标准的预置的方法,具体操做以下。
1)引入自定义apex类的方法:咱们在项目中和后台apex代码交互,首先须要作的就是使用此标签引入须要用到的类的方法。正则表达式

1 import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
2 @wire(apexMethod, { apexMethodParams })
3 propertyOrFunction;

针对此函数相关的变量在上一篇有细节描述,除了引入自定义apex方法之外,还有其余的一些封装的标准的方法。
2)getSObjectValue(sobject, fieldApiName):此方法用与从一个object中获取指定的field的值。这个object是从apex中搜索出来的。
此方法两个参数,sobject表明从后台apex中搜索出来的数据,fieldApiName为想要查询字段值的API name。fieldApiName能够是String类型的api name也能够经过@salesforce/schema方式引入进来。咱们在搜索时可能获取父层数据,好比搜索opportunity数据时须要获取其对应的account的owner信息,此种父查询展现的最大深度为5层,好比Opportunity.Account.CreatedBy.LastModifiedBy.Name。 
头部须要引用:import { getSObjectValue } from '@salesforce/apex';而后调用此方法便可。api

getSObjectValueDemo.html缓存

1 <template>
2     {accountOwnerName}
3 </template>

getSObjectValueDemo.js:调用findOpportunity后台方法,此方法搜索了Opportunity的Account.Owner.Name,咱们可使用getSObjectValue获取其字段结果。函数

 1 import { LightningElement, wire } from 'lwc';
 2 import findOpportunity from '@salesforce/apex/OpportunityController.findOpportunity';
 3 import { getSObjectValue } from '@salesforce/apex';
 4 import OPPORTUNITY_ACCOUNT_OWNER_NAME from '@salesforce/schema/Opportunity.Account.Owner.Name';
 5 export default class GetSObjectValueDemo extends LightningElement {
 6 
 7     @wire(findOpportunity,{searchKey:'test'})
 8     opportunityList;
 9 
10     get accountOwnerName() {
11         if(this.opportunityList.data !== undefined) {
12             const opportunity = this.opportunityList.data[0];
13             return getSObjectValue(opportunity,OPPORTUNITY_ACCOUNT_OWNER_NAME);
14         }
15         return '';
16     }
17 }

OpportunityController.clsui

 1 public with sharing class OpportunityController {
 2     @AuraEnabled(cacheable=true)
 3     public static List<Opportunity> findOpportunity(String searchKey){
 4         String key = '%' + searchKey + '%';
 5         return [SELECT Id,Account.Owner.Name
 6                     FROM Opportunity
 7                     WHERE Name like :key 
 8                     ORDER BY LastModifiedDate DESC
 9                     limit 1];
10     }
11 }

3)refreshApex(wiredProperty):用于使用wire注解状况下针对缓存变量的刷新,此方法只针对缓存变量,其余状况没法使用。this

头部须要引用:import { refreshApex } from '@salesforce/apex';
详情用法能够查看上一篇。spa

4)@salesforce/apexContinuation:主要用于长时间运行的callout,此功能后期会单独描述。

5)@salesforce/label:用于引入custom label。
头部须要引入:import labelName from '@salesforce/label/labelReference'
其中:
labelName为咱们起的名字,后期js以及前台html中用到此custom label的地方须要使用此名字做为引用
labelReference为在咱们org中声明的custom label的label name。引入时须要使用namespace.labelName格式进行引用,若是不是manage package,默认的namespace为c。

由于咱们在js中可能获取多个custom label,因此咱们能够封装在一个label的变量中,经过label.labelName方式获取。custom label咱们声明的时候会有两种形式,一种是正常的,另一种是可使用{0}{1}这种format的操做的label。针对classic以及lightning aura咱们能够很轻易的对format的label进行处理,遗憾的是针对lwc并无直接的方式去处理,咱们可使用正则表达式进行函数处理。

stringUtils.js:用于解析字符串中使用{}处理的占位符。

1 const formatString = (stringForFormat,params) => {
2     let str = stringForFormat;
3     for (let i = 0; i < params.length; i++) {
4         let re = new RegExp('\\{' + i + '\\}', 'gm');
5         str = str.replace(re, params[i]);
6     }
7     return str;
8 };
9 export {formatString};

getCustomLabelDemo.js:引入方法,针对包含format的字符串进行处理。

 1 import { LightningElement } from 'lwc';
 2 import sampleLabel from '@salesforce/label/c.sample_label';
 3 import sampleLabelWithParam from '@salesforce/label/c.sample_label_with_param';
 4 import {formatString} from 'c/stringUtils';
 5 export default class GetCustomLabelDemo extends LightningElement {
 6 
 7     get formatedSampleLabelWithParam() {
 8         let paramList = new Array();
 9         paramList.push('xx');
10         return formatString(sampleLabelWithParam,paramList);
11     }
12 
13     label = {
14         sampleLabel
15     };
16 }

getCustomLabelDemo.html:展现两个custom label

1 <template>
2     {label.sampleLabel}
3     <br/>
4     {formatedSampleLabelWithParam}
5 </template>

显示结果:

6)@salesforce/resourceUrl:引入static resource。头部根据当前的静态资源是否在managed package中有两种引用的方式:

1 import resourceName from '@salesforce/resourceUrl/resourceReference';
2 import myResource from '@salesforce/resourceUrl/namespace__resourceReference';

demo以下:

 useStaticResourceDemo.js:引入static resource,在sample目录下有一个sample.png图片,前台展现此图片

1 import { LightningElement } from 'lwc';
2 import sampleResource from '@salesforce/resourceUrl/lwc_sample';
3 export default class UseStaticResourceDemo extends LightningElement {
4     pictureSampleURL = sampleResource + '/sample/sample.png';
5 }

useStaticResourceDemo.html:展现此图片

1 <template>
2     <img src={pictureSampleURL}/>
3 </template>

效果展现:

7)@salesforce/schema:引入object以及field的引用。当咱们使用LDS或者wire service获取字段的引用时,官方建议咱们使用此种方式而不是字符串方式,详细使用操做能够查看上一篇博客。

8)@salesforce/user:获取当前user的信息。经过此引用能够获取当前user的id 以及当前user是不是一个community guest user。咱们经过

import property from '@salesforce/user/property';来引用,property有两个值:Id / isGuest.下面是一个关于user信息的获取的demo。

getUserInfoDemo.js

1 import { LightningElement } from 'lwc';
2 import Id from '@salesforce/user/Id';
3 import isGuest from '@salesforce/user/isGuest';
4 export default class GetUserInfoDemo extends LightningElement {
5     userId = Id;
6     isGuestUser = isGuest;
7 }

getUserInfoDemo.html

1 <template>
2     current user Id : {userId}<br/>
3     current user is Guest {isGuestUser}
4 </template>

以上的内容为@salesforce模块封装的主要方法,详情还请自行查看文档。接下来的几部分咱们讲的主要是 lightning/ui*Api部分的wire adapter,其主要是为了扩充LDS标准之外的加强方法。LWC针对数据的操做以及解析以下图所示。LWC wire adapter以及LDS转成的都是User Interface API中的内容,因此若是想更好的了解各个wire adapter的使用以及返回类型的详情还请查看User Interface API。下载地址:https://resources.docs.salesforce.com/220/latest/en-us/sfdc/pdf/api_ui.pdf

二. lightning/uiListApi

此模块主要用于针对一个list view获取数据以及metadata。咱们针对某个对象数据建立列表视图时,会进行相关的filter,展现某些固定的列,展现多少数据等操做。使用lightning/uiListApi模块咱们能够经过object的api name等信息即可以获取到指定的list view的数据。须要注意一点的是,此模块以及模块中的方法目前是beta功能。

1. getListUi:此wire adapter方法用于获取list view中的数据。咱们能够经过几个参数以及几种形式获取数据。

1) 使用 object 的api name以及 list view的api name去获取数据;

1 import { getListUi } from 'lightning/uiListApi';
2 @wire(getListUi, { objectApiName: objName, listViewApiName: listViewName })
3 propertyOrFunction;

其中objName表明想要获取哪一个表的数据,取得是表的api name
listViewName取得是当前表的哪一个list view的数据,取得是 list view的api name
2)使用list view的id 获取数据;

1 import { getListUi } from 'lightning/uiListApi';
2 @wire(getListUi, { listViewId:listViewId})
3 propertyOrFunction;

3)使用object 的api name以及MRU(Most Recently Used)去获取数据.咱们在每一个表的list view中都有一个rencent view的视图,这个是标准的一个视图,LWC针对此视图有专门的取法。

1 import { getListUi, MRU } from 'lightning/uiListApi';
2 @wire(getListUi, { objectApiName: objectName, listViewApiName: MRU })
3 propertyOrFunction;

除了上述的必传的参数之外,此适配器方法还提供了其余的可选参数,好比pageSize等。

https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_resources_list_views_records_md.htm#request_parameters

https://developer.salesforce.com/docs/atlas.en-us.uiapi.meta/uiapi/ui_api_resources_mru_list_views_records.htm

 1 import { LightningElement, wire,track } from 'lwc';
 2 import {getListUi} from 'lightning/uiListApi';
 3 import ACCOUNT_OBJECT from '@salesforce/schema/Account';
 4 export default class GetListUIDemo extends LightningElement {
 5     @track error;
 6     @track accountList;
 7     @wire(getListUi,{objectApiName:ACCOUNT_OBJECT,listViewApiName:'AllAccounts',pageSize:100})
 8     wiredAccountList({error,data}) {
 9         if(data) {
10             this.accountList = data.records.records;
11             this.error = undefined;
12         } else if(error) {
13             this.error = error;
14             this.accountList = undefined;
15         }
16     }
17 }

getListUIDemo.html

 1 <template>
 2     <lightning-card title="get list ui demo" icon-name="standard:action_list_component">
 3  
 4         <table class="slds-table slds-table_cell-buffer slds-table_bordered">
 5             <thead>
 6                 <tr class="slds-line-height_reset">
 7                     <th class="" scope="col">
 8                         <div class="slds-truncate">Account Id</div>
 9                     </th>
10                     <th class="" scope="col">
11                         <div class="slds-truncate">Account Name</div>
12                     </th>
13                     <th class="" scope="col">
14                         <div class="slds-truncate">Type</div>
15                     </th>
16                     <th class="" scope="col">
17                         <div class="slds-truncate">Phone</div>
18                     </th>
19                 </tr>
20             </thead>
21             <tbody>
22                 <template if:true={accountList}>
23                     <template for:each={accountList} for:item="account">
24                         <tr key={account.id}>
25                             <td>{account.id}</td>
26                             <td> {account.fields.Name.value}</td>
27                             <td> {account.fields.Type.value}</td>
28                             <td> {account.fields.Phone.value}</td>
29                         </tr>
30                     </template>
31                 </template>
32                 <template if:false={accountList}>
33                     List View is not contains any data
34                 </template>
35             </tbody>
36         </table>
37     </lightning-card>
38 </template>

结果展现:

 三. lightning/uiObjectInfoApi

此模块的适配器方法用于获取object的metadata以及picklist的value。

1. getObjectInfo:使用wire adapter针对指定的object获取相关的metadata。response包括描述fields/ child relationships / record type/theme metadata信息。下图能够看到咱们demo中用到的获取Account的getObjectInfo的结构。咱们对于apex中的Schema有了解状况下,能够理解成此适配器至关于DescribeSObjectResult以及相关的方法用来获取相关的metadata信息。demo中咱们会演示获取某个字段的label信息,感兴趣的能够自行研究。

 

 getSObjectInfoDemo.js:获取Account表中的AccountSource的label值

 1 import { LightningElement,wire } from 'lwc';
 2 import { getObjectInfo } from 'lightning/uiObjectInfoApi';
 3 import ACCOUNT_OBJECT from '@salesforce/schema/Account';
 4 export default class GetObjectInfoDemo extends LightningElement {
 5     @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
 6     accountInfo;
 7 
 8     get recordInfo() {
 9         if(this.accountInfo.data !== undefined) {
10             return this.accountInfo.data.fields.AccountSource.label;
11         }
12         return '';
13     }
14 }

getSObjectInfoDemo.html:展现AccountSource的label值

1 <template>
2     {recordInfo}
3 </template>

2. getPicklistValues:使用此wire adapter获取某个 picklist类型字段的picklist value。咱们接触apex知道,picklist 字段获取可使用两种方式,基于record type方式获取某个record type的picklist values以及获取picklist类型字段的全部的values。此wire adapter为经过record type获取values。此wire adapter须要传两个参数,第一个参数是object的某个record type id,第二个参数是想要获取的picklist类型的字段API名称。

@wire(getPicklistValues, { recordTypeId: recordTypeId, fieldApiName: fieldApiName })
propertyOrFunction;

其中,recordTypeId为咱们想要操做的指定record type的ID。咱们能够根据getObjectInfo 或者getRecordUi这两个wire adapter获取。此变量为必填字段,咱们若是想变量改变getPicklistValues动态改变,咱们可使用'$'符号去封装此变量;fieldApiName为想要查询字段的API name,这里推荐使用@salesforce/schame去获取field api的reference。返回的类型有两种,变量或者是方法,变量封装data和error两个子变量,使用方法咱们能够将这两个做为参数进行展现。详见上篇的propertyOrFunction的使用。

下面的demo咱们来获取account中的industry的picklist values。

getObjectInfoDemo.js:首先咱们先使用getObjectInfo获取Account的schema信息,而后经过getPicklistValues获取picklist信息,这里使用$做为动态传参,保证当objectInfo变量先装载,装载之后执行getPicklistValues。

 1 import { LightningElement,wire} from 'lwc';
 2 import { getObjectInfo } from 'lightning/uiObjectInfoApi';
 3 import ACCOUNT_OBJECT from '@salesforce/schema/Account';
 4 import {getPicklistValues} from 'lightning/uiObjectInfoApi';
 5 import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
 6 export default class GetObjectInfoDemo extends LightningElement {
 7 
 8     @wire(getObjectInfo,{objectApiName:ACCOUNT_OBJECT})
 9     objectInfo;
10 
11     @wire(getPicklistValues,{ recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: ACCOUNT_INDUSTRY_FIELD })
12     industryList;
13 }

getObjectInfoDemo.html:使用for:each进行遍历industry list,使用select option进行展现数据。

 1 <template>
 2     <lightning-card title="Industry List ">
 3         <template if:true={industryList.data}>
 4             <div class="slds-m-around_medium">
 5                 <select>
 6                     <template for:each={industryList.data.values} for:item="item">
 7                         <option key={item.value}>{item.label}</option>
 8                     </template>
 9                 </select>
10             </div>
11         </template>
12     </lightning-card>
13 </template>

效果以下:

 3. getPicklistValuesByRecordType:此方法用于获取某个对象,某个record type的全部的picklist 的values,这些picklist values封装在一个map中。

@wire(getPicklistValuesByRecordType, { objectApiName: objectName, recordTypeId: recordTypeId })
propertyOrFunction

其中objectName为想要获取的object的全部的picklist values的object api name,此字段必填,推荐使用@salesforce/schema获取,recordTypeId也是必填字段,获取方式同上一个wire adapter。咱们经过一个例子更好的理解。

getPicklistValuesByRecordTypeDemo.js:用来获取record type名称为 Test Record Type的全部的picklist values信息。

 1 import { LightningElement, wire,track } from 'lwc';
 2 import {getObjectInfo} from 'lightning/uiObjectInfoApi';
 3 import ACCOUNT_OBJECT from '@salesforce/schema/Account';
 4 import {getPicklistValuesByRecordType} from 'lightning/uiObjectInfoApi';
 5 export default class GetPicklistValuesByRecordTypeDemo extends LightningElement {
 6     @track recordTypeId = '';
 7     @wire(getObjectInfo,{objectApiName:ACCOUNT_OBJECT})
 8     getObjectInfo({data,error}) {
 9         if(data) {
10             const allRecordTypeInfos = data.recordTypeInfos;
11             // eslint-disable-next-line no-console
12             console.log(JSON.stringify(allRecordTypeInfos));
13             this.recordTypeId = Object.keys(allRecordTypeInfos).find(rti => allRecordTypeInfos[rti].name === 'Test Record Type');
14         } else if(error) {
15             //TODO
16         }
17     }
18 
19     @wire(getPicklistValuesByRecordType,{ objectApiName: ACCOUNT_OBJECT, recordTypeId: '$recordTypeId'})
20     picklistValues;
21 
22     get demo() {
23         // eslint-disable-next-line no-console
24         console.log(JSON.stringify(this.picklistValues));
25         return this.recordTypeId;
26     }
27 
28 }

这里咱们使用getObjectInfo获取全部的record type,打印出来的all record type 信息以下所示,咱们能够看出来,它的结果集是一个Map,key是record type id,value封装了相关的细节信息,咱们使用Object.key.find来获取指定名称的record type id信息。此使用方法是javascript的遍历map的使用,感兴趣的能够自行查看。

 

 经过record type id咱们使用getPicklistValuesByRecordType获取全部的picklist valus,格式的层级模式以下图所示。

 获取到层级模式之后,咱们对程序进行一下加强,获取全部的AccountSource的picklist values。

在上面的js方法中添加此方法。

1 get accountSourcePicklistValues() {
2    // eslint-disable-next-line no-console
3    console.log(JSON.stringify(this.picklistValues));
4    if(this.picklistValues !== undefined && this.picklistValues.data !== undefined) {
5        return this.picklistValues.data.picklistFieldValues.AccountSource.values;
6     }
7     return '';
8 }

getPicklistValuesByRecordTypeDemo.html

 1 <template>
 2     <lightning-card title="Account Source List ">
 3         <template if:true={accountSourcePicklistValues}>
 4             <div class="slds-m-around_medium">
 5                 <select>
 6                     <template for:each={accountSourcePicklistValues} for:item="item">
 7                         <option key={item.value}>{item.label}</option>
 8                     </template>
 9                 </select>
10             </div>
11         </template>
12     </lightning-card>
13 </template>

效果展现:

三. lightning/uiRecordApi

此模块中的wire adapter主要用于进行数据的CRUD。下面列举几个主要的方法,其余的方法还请自行查看文档。

1. getRecord:用于经过record id获取此id对应的record 信息,详情用法以及参数介绍参看上一篇,有详细描述。

1 @wire(getRecord, { recordId: string, fields: string[], optionalFields?: string[])
2 propertyOrFunction
3 
4 @wire(getRecord, { recordId: string, layoutTypes: string[],
5                    modes?: string[], optionalFields?: string[])
6 propertyOrFunction

2. getRecordUi:使用此wire adapter能够针对一条或者多条记录获取其对应的page layout,metadata以及在UI上面的数据信息。咱们上面也讲过若是想要获取record type id也可使用此wire adapter。

1 @wire(getRecordUi, { recordIds: string, layoutTypes: string,
2                        modes: string, optionalFields?: string[] })
3 propertyOrFunction;
4 
5   @wire(getRecordUi, { recordIds: string[], layoutTypes: string[], 
6                        modes: string[], optionalFields?: string[] })
7 propertyOrFunction;

能够看到参数和getRecord很类似,返回的对象为Record UI对象以及error两个。咱们能够在User Interface中封装的Record UI查看返回的结构以及如何获取须要的内容信息。返回的层级结构以及信息以下图所示,咱们只须要根据不一样的取值须要获取不一样的值便可。

3. getFieldValue(record,field):此方法用于获取记录中指定field API对应的value。须要注意的是,他获取的永远是API value。此方法的demo在上一篇有介绍,能够查看上一篇。

4. getFieldDisplayValue(record,field):此方法相对上一个方法的区别为此方法获取的是展现的value。好比一个picklist字段,咱们有国际化操做,针对picklist value多是英文,可是咱们对其中文进行translation,那么针对语言为中文的客户,getFieldValue获取的是picklist 的value,即英文的值,getFieldDisplayValue获取的是中文的值。

 getFieldDisplayValueDemo.js:此方法用于获取Account Source的value以及display value

 1 import { LightningElement,api, wire } from 'lwc';
 2 import {getRecord} from 'lightning/uiRecordApi';
 3 import {getFieldValue} from 'lightning/uiRecordApi';
 4 import {getFieldDisplayValue} from 'lightning/uiRecordApi';
 5 import ACCOUNT_ACCOUNT_SOURCE from '@salesforce/schema/Account.AccountSource';
 6 export default class GetFieldDisplayValueDemo extends LightningElement {
 7     @api recordId;
 8 
 9     @wire(getRecord,{recordId:'$recordId',fields:[ACCOUNT_ACCOUNT_SOURCE]})
10     account;
11 
12     get accountSourceValue() {
13         if(this.account.data !== undefined) {
14             return getFieldValue(this.account.data,ACCOUNT_ACCOUNT_SOURCE);
15         }
16         return '';
17     }
18 
19     get accountSourceDisplayValue() {
20         if(this.account.data !== undefined) {
21             return getFieldDisplayValue(this.account.data,ACCOUNT_ACCOUNT_SOURCE);
22         }
23         return '';
24     }
25 }

getFieldDisplayValueDemo.html

1 <template>
2     value : {accountSourceValue}<br/>
3     label : {accountSourceDisplayValue}
4 </template>

效果展现

5. createRecord(recordInput: Record):此方法用于建立一条记录,其中Record咱们须要使用wire service提供的generateRecordInputForCreate(record,objectInfo) 这个wire adapter去实例化一个Record。返回类型为一个Promise,即当前的这个Record,包括当前记录的page layout中的信息。使用createRecord以及使用updateRecord这两个方法前须要先思考是否可使用lightning-record-form以及lightning-record-edit-form去搞定。搞定不了状况下在使用wire adapter。此wire adapter官方提供了简单的demo,查看此连接即可以更好的了解此wire adapter:https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.data_salesforce_write

6. updateRecord(recordInput, clientOptions):同上方法,用于编辑一条记录,参数中的recordInput须要使用wire service提供的generateRecordInputForUpdate(record,objectInfo)去搞定,仍是和上面的同样,若是实在搞定不了在使用此方法,不然尽可能别用。

7. deleteRecord(recordId):用于删除一条记录,传入当前的record id便可实现删除操做。方法为void类型,没有返回内容。

总结:篇中简单的整理了一些针对@salesforce 以及 lightning/record*Api模块的方法,细节的方法描述还请自行查看官方文档以及User Interface API。其实除了这两个module,LWC还提供了不少好用的module,好比lightning/platformShowToastEvent用于展现toast信息等等,还要靠小伙伴本身挖掘。另外须要注意的一点的是,针对wire service的这些wire adapter,若是可使用lightning:record-form相关的搞定,能不用尽可能不用,标准功能搞定不了在考虑使用。篇中有错误地方欢迎指出,有不懂的欢迎提问。

相关文章
相关标签/搜索