本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type)javascript
Salesforce lwc中给咱们提供了不少优秀的wire adapter使咱们的开发更加便捷,好比getPicklistValues以及getPicklistValuesByRecordType
react
能够实现获取某个字段或者某个record type全部picklist类型字段的 picklist values。这个组件在便捷的同时又让咱们心生哀怨,由于他不是全部的对象都支持,针对经常使用对象 Account / Opportunity / Contact 或者自定义对象等能够直接使用,方便快捷,可是针对一些对象则不支持,好比 Event & Task。 因此当项目中使用到 Event & Task 进行自定义开发须要获取某个或者某些字段的 picklist values的值时,若是需求不变,咱们进行 hard code,将全部的 label-value键值对使用 {label,value}的map进行封装,此种需求只是针对不常常修改的场景。若是需求不明确,或者须要指定的record type显示指定的picklist values,而 record type配置的 picklist values又能够实时变更的场景来讲简直是灾难的,因此有了这篇的针对 LwC公用的方法的实现思路。代码并不完善,思路仅供参考。
api
思路分析:异步
1. 后台如何构建,须要知足哪些场景;async
2. 前台如何搭建,如何作成公用组件使大部分的场景均可以简单引用即可以使用。函数
伴随着这两个问题进行了考虑。oop
1) 针对后台搭建,暂时知足两个场景post
2)针对前台的搭建,由于须要从后台获取数据,须要保证数据获取支持异步处理,即数据处理完进行picklist 数据赋值。
思路分析之后进行功能的构建,本篇参考之前写过的一篇文章,这里 PicklistDescriber代码便不在放出,直接引用。
一. 后台搭建
CommonUtilsController:由于Salesforce目前没有针对 包含 record type对应的 Picklist values的特别好的获取方法,因此咱们根据之前的XML解析模式进行获取包含record type的场景。 不少人可能会说Salesforce支持了经过user interface方式获取,只须要一个callout就能够获取到包含record type对应的picklist字段对应的values。这种方式其实和wire adapter原理同样,只是针对一部分object,而不是针对全部的object,考虑到组件的共用性,因此放弃了那种方式。
public without sharing class CommonUtilsController { private static Map<String,Schema.SObjectType> globalDescribeMap = Schema.getGlobalDescribe(); @AuraEnabled(cacheable=true) public static Map<String,Map<String,String>> getPicklistMapByObject(String objectName) { Map<String,Map<String,String>> resultMap = new Map<String, Map<String,String>>(); Schema.DescribeSObjectResult objectResult = getDescribeObjectResult(objectName); Map<String,SObjectField> fieldsMap = objectResult.fields.getMap(); Map<String,Schema.DescribeFieldResult> picklistName2DescribeFieldMap = new Map<String,Schema.DescribeFieldResult>(); for(String fieldName : fieldsMap.keySet()) { SObjectField objField = fieldsMap.get(fieldName); Schema.DescribeFieldResult fieldResult = objField.getDescribe(); if(fieldResult.getType() == Schema.DisplayType.Picklist) { picklistName2DescribeFieldMap.put(fieldName,fieldResult); } } if(!picklistName2DescribeFieldMap.isEmpty()) { for(String fieldName : picklistName2DescribeFieldMap.keySet()) { Schema.DescribeFieldResult fieldResult = picklistName2DescribeFieldMap.get(fieldName); List<Schema.PicklistEntry> picklistEntries = fieldResult.getPicklistValues(); Map<String,String> fieldValue2LabelMap = new Map<String,String>(); for(Schema.PicklistEntry picklistEntry : picklistEntries) { if(picklistEntry.isActive()) { fieldValue2LabelMap.put(picklistEntry.getValue(),picklistEntry.getLabel()); } } resultMap.put(fieldName,fieldValue2LabelMap); } } return resultMap; } @AuraEnabled(cacheable=true) public static Map<String,String> getPicklistMapByObjectAndField(String objectName,String field,String recordTypeDevelopName) { Map<String,String> resultMap = new Map<String,String>(); Schema.DescribeSObjectResult objectResult = getDescribeObjectResult(objectName); Map<String,SObjectField> fieldsMap = objectResult.fields.getMap(); if(fieldsMap.containsKey(field)) { SObjectField objField = fieldsMap.get(field); Schema.DescribeFieldResult fieldResult = objField.getDescribe(); List<Schema.PicklistEntry> picklistEntries = fieldResult.getPicklistValues(); for(Schema.PicklistEntry picklistEntry : picklistEntries) { if(picklistEntry.isActive()) { resultMap.put(picklistEntry.getValue(),picklistEntry.getLabel()); } } if(String.isNotBlank(recordTypeDevelopName)) { List<String> picklistValueWithRecordTypeList = PicklistDescriber.describe(objectName,recordTypeDevelopName,field); Map<String,String> resultForRecordTypeMap = new Map<String,String>(); for(String picklistValue : picklistValueWithRecordTypeList) { if(resultMap.containsKey(picklistValue)) { resultForRecordTypeMap.put(picklistValue,resultMap.get(picklistValue)); } } return resultForRecordTypeMap; } } return resultMap; } private static Schema.DescribeSObjectResult getDescribeObjectResult(String objectName) { Schema.SObjectType objectType = globalDescribeMap.get(objectName); Schema.DescribeSObjectResult objectResult = objectType.getDescribe(); return objectResult; } }
后台就这样搭建完成,暴露了两个方法:getPicklistMapByObject & getPicklistMapByObjectAndField。第一个方法用来获取一个表的全部 Picklist类型字段的label api name对,key为api name,value为picklist的label。咱们以 Account表为例,返回的结构相似以下图所示:
第二个方法用来获取某个指定object指定字段的 picklist values的获取,有record type则传递,若是不须要record type则传递 null或者不传递便可。针对结果集来讲则没有外层的field api name,直接就是 picklist 字段的 api value -> label,这里不作截图。
二. 前台搭建
这里须要分红两步, 第一步是作一个公用组件来实现 传递相关参数获取指定的咱们想获得的结果集。
picklistUtils.js:封装了两个公用函数,getAllPicklist用于获取object全部的picklist 类型字段的结果集;getFieldPicklistMap用于经过object & field [record type developer name]来获取指定字段的结果集。
import getPicklistMapByObject from '@salesforce/apex/CommonUtilsController.getPicklistMapByObject'; import getPicklistMapByObjectAndField from '@salesforce/apex/CommonUtilsController.getPicklistMapByObjectAndField'; const getAllPicklist = (objectAPIName) => { //let resultMap = new Map(); return getPicklistMapByObject({objectName:objectAPIName}) .then(result => { return result; }) .catch(error =>{ console.log(error); }); }; const getFieldPicklistMap = (objectAPIName, fieldAPIName, recordTypeDevelopName) => { return getPicklistMapByObjectAndField({objectName:objectAPIName,field:fieldAPIName,recordTypeDevelopName:recordTypeDevelopName}) .then(result => { return result; }) .catch(error =>{ console.log(error); }); } export {getAllPicklist,getFieldPicklistMap};
当咱们将代码赋值粘贴到vs code里面,咱们会发现他有一个提示: This may be converted to an async function.为何会有这样的提示呢?是由于咱们这个从后台进行结果集获取,此步骤不是实时的,而是一个异步的操做,因此他提示了将会将这个转换成了一个异步的函数。
这样的解释可能过于干燥,什么是异步的?异步怎么处理呢?这里放一个连接用来更好的理解:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function。当咱们声明了异步函数,调用源调用它时须要使用await去共同使用,从而实现结果集返回时能够正常的接收以及处理。
import { LightningElement,track } from 'lwc'; import {getAllPicklist} from 'c/picklistUtils'; export default class AccountPicklistComponent extends LightningElement { @track industryList = []; @track typeList = []; @track accountSourceList = []; @track ratingList = []; async connectedCallback() { const result = await getAllPicklist('Account'); console.log('total result : ' + JSON.stringify(result)); let typeTempList = []; let industryTempList = []; let accountSourceTempList = []; let ratingTempList = []; for(let key in result) { if (result.hasOwnProperty(key)) { // Filtering the data in the loop if(key === 'type') { let typeResult = result[key]; console.log('type result : ' + JSON.stringify(typeResult)); for(let typeValue in typeResult) { typeTempList.push({label:typeResult[typeValue],value:typeValue}); } } else if(key === 'industry') { let industryResult = result[key]; for(let industryValue in industryResult) { industryTempList.push({label:industryResult[industryValue],value:industryValue}); } } else if(key === 'accountsource') { let accountSourceResult = result[key]; for(let accountSourceValue in accountSourceResult) { accountSourceTempList.push({label:accountSourceResult[accountSourceValue],value:accountSourceValue}); } } else if(key === 'rating') { let ratingResult = result[key]; for(let ratingValue in ratingResult) { ratingTempList.push({label:ratingResult[ratingValue],value:ratingValue}); } } } } this.typeList = typeTempList; this.industryList = industryTempList; this.accountSourceList = accountSourceTempList; this.ratingList = ratingTempList; } }
accountPicklistComponent.html:用来展现相关字段的select option
<template> <lightning-card> <lightning-layout multiple-rows="true"> <lightning-layout-item size="6"> <lightning-combobox name="industry" label="industry" options={industryList}> </lightning-combobox> </lightning-layout-item> <lightning-layout-item size="6"> <lightning-combobox name="type" label="type" options={typeList}> </lightning-combobox> </lightning-layout-item> <lightning-layout-item size="6"> <lightning-combobox name="accountSource" label="Account Source" options={accountSourceList}> </lightning-combobox> </lightning-layout-item> <lightning-layout-item size="6"> <lightning-combobox name="rating" label="rating" options={ratingList}> </lightning-combobox> </lightning-layout-item> </lightning-layout> </lightning-card> </template>
结果展现:这个表的相关字段的picklist值即可以动态取出
总结:篇中只是根据某种需求去分析思考并进行代码的编写。代码并无进行优化以及异常处理。篇中有错误地方还请指出,有不懂欢迎留言。有更好的方式欢迎沟通。