上一篇中咱們在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) 使用 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等。
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相關的搞定,能不用盡可能不用,標準功能搞定不了在考慮使用。篇中有錯誤地方歡迎指出,有不懂的歡迎提問。