我們做的項目好多都是多語言的項目,針對不同國家需要展示不同的語言的標題。我們在classic中的VF page可謂是得心應手,因為系統中已經封裝好了我們可以直接在VF獲取label/api name等方法。但是我們在lightning aura中開發卻發現這個常用的功能並沒有包含,好吧,既然沒有現成可用的那我們就要有workaround的方式去后台獲取。此篇主要封裝好組件去實現獲取某個object或者某些object相關字段的label。
那我們來開始進行這個組件的開發,開發以前我們需要先思考一下,組件化的東西,傳參應該是什么,返回應該是什么,應該實現哪些功能解決哪些痛點。如何用到更好的優化。本人思考可能並不特別的完全,感興趣的可以進行優化。
1. object 的API name應該為必填項。 這里應該實現可以同時獲取多個表的字段的label信息,我們畫component時,很可能需要獲取當前的對象,父對象以及相關的子對象的字段的label,所以此處傳參應該能做到傳遞list而不是單一的object
2. object對應的指定的field的api name列表,此項應該為可選項,非必填。我們都知道aura開發現在很慢,而且我們在前台獲取label時,可能一個object有上百個字段,但是我們在頁面只需要某幾個字段的label的信息,如果全部查出來放在前台特別影響view state,所以我們此處應該支持可以通過指定的一些字段進行查詢。因為object傳參是list,所以此參數應該為Map<String,List<String>>方式。
3. 返回類型應該為 Map<String,Map<String,String>>類型,外層的key是objectAPIName,內層的map的key是fieldAPIName,內層的map的value為我們需要的field label
OK,上面的已經梳理出來,那干就完了。
一. 公用組件搭建
FieldLabelServiceController.cls 用於后台搭建查詢指定的obj / field的value -> label信息
1 public with sharing class FieldLabelServiceController { 2 /* 3 * @param objApiNameList : object API name list. eg:['Account','Contact'] 4 * @param objApiName2FieldsMap: object API name 2 fields map. eg:{'Account':['Name','Type'],'Contact':['LastName','Phone']} 5 * @return object API name 2 map of field API name -> label name. eg:{'Account':{'Type':'類型'},'Contact':{'LastName':'姓'}} 6 */ 7 @AuraEnabled 8 public static Map<String,Map<String,String>> getFieldLabelService(List<String> objApiNameList,Map<String,List<String>> objApiName2FieldsMap) { 9 // key: object API name ; value : (Map: key:field API name, value: field label) 10 Map<String,Map<String,String>> object2FieldLabelMap = new Map<String,Map<String,String>>(); 11 //get all sobject sObjectType map 12 Map<String,sObjectType> objName2ObjTypeMap = Schema.getGlobalDescribe(); 13 for(String objApiName : objApiNameList) { 14 15 //1. get specific object sObjectType 16 sObjectType objType = objName2ObjTypeMap.get(objApiName); 17 //2. get all of the fields map via specific object 18 Map<String,Schema.SObjectField> fieldsMap = objType.getDescribe().fields.getMap(); 19 20 //3. check if retrieve specific field list or all the fields mapping via object 21 Set<String> retrieveFieldList = new Set<String>(); 22 if(objApiName2FieldsMap != null && objApiName2FieldsMap.containsKey(objApiName)) { 23 retrieveFieldList = new Set<String>(objApiName2FieldsMap.get(objApiName)); 24 } 25 26 Map<String,String> fieldApiName2FieldLabelMap = new Map<String,String>(); 27 //4. get all / specific field api name -> label name mapping 28 for(String fieldApiName : fieldsMap.keySet()){ 29 if(retrieveFieldList.size() > 0 && !retrieveFieldList.contains(String.valueOf(fieldsMap.get(fieldApiName)))) {30 continue; 31 } 32 33 String label = fieldsMap.get(fieldApiName).getDescribe().getLabel(); 34 fieldApiName2FieldLabelMap.put(String.valueOf(fieldsMap.get(fieldApiName)), label == null ? fieldApiName : label); 35 } 36 37 object2FieldLabelMap.put(objApiName, fieldApiName2FieldLabelMap); 38 } 39 return object2FieldLabelMap; 40 } 41 }
FieldLabelService.cmp:用於封裝共用方法
1 <aura:component access="global" description="Field label service" controller="FieldLabelServiceController"> 2 <aura:method access="global" name="getFieldLabel" action="{!c.getFieldLabelAction}"> 3 <aura:attribute type="List" name="objectAPINameList" required="true" description="object list to retrieve field label" /> 4 <aura:attribute type="Map" name="objectFieldAPINameMap" description="specific fields need to retrieve via object api name"/> 5 <aura:attribute type="Function" name="callback" required="true" /> 6 </aura:method> 7 </aura:component>
FieldLabelServiceController.js:用於封裝對應的controller js方法,調用后台獲取結果
1 ({ 2 getFieldLabelAction : function(component, event, helper) { 3 const params = event.getParam('arguments'); 4 const action = component.get('c.getFieldLabelService'); 5 action.setParams({ 6 "objApiNameList" : params.objectAPINameList, 7 "objApiName2FieldsMap":params.objectFieldAPINameMap 8 }); 9 action.setCallback(this, function(response) { 10 const state = response.getState(); 11 if (state === 'SUCCESS') { 12 params.callback(response.getReturnValue()); 13 } else if (state === 'ERROR') { 14 const errors = response.getError(); 15 if (errors) { 16 console.error(JSON.stringify(errors)); 17 } else { 18 console.error('Unknown error'); 19 } 20 } 21 }); 22 23 $A.enqueueAction(action); 24 } 25 })
至此組件封裝完成,下面是調用部分。調用部分沒有UI,感興趣的自行畫UI。
二. 公用組件測試
FieldLabelTestComponent:用於引入公用組件,並且初始化獲取Account/Contact的field label。
<aura:component implements="flexipage:availableForAllPageTypes"> <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> <aura:attribute name="accountFieldLabelMap" type="Map"/> <aura:attribute name="contactFieldLabelMap" type="Map"/> <c:FieldLabelService aura:id="service"/> </aura:component>
FieldLabelTestComponentController.js:用於后台調用公用組件的方法,傳值,針對response進行解析獲取自己需要的內容。demo中針對account只獲取name以及type的值,對contact獲取所有字段的label值。
1 ({ 2 doInit : function(component, event, helper) { 3 const service = component.find('service'); 4 let objectAPINameList = ['Account','Contact']; 5 let objectFieldAPINameMap = {'Account':['Name','Type']}; 6 service.getFieldLabel(objectAPINameList,objectFieldAPINameMap,function(result) { 7 console.log(JSON.stringify(result)); 8 component.set('v.accountFieldLabelMap',result['Account']); 9 component.set('v.contactFieldLabelMap',result['Contact']); 10 console.log(JSON.stringify(result['Account'])); 11 console.log(JSON.stringify(result.Account)); 12 }); 13 } 14 })
結果展示:針對account只獲取了指定的字段的label,Contact獲取了所有的label信息。可以使用[]方式或者.的方式獲取詳細內容。
總結:篇中簡單的介紹了針對aura情況下獲取field label的公用組件的實現。篇中有錯誤的地方歡迎指出,有不懂的歡迎留言,有可以優化的地方歡迎交流並且鼓勵優化。