1. 程式人生 > >salesforce lightning零基礎學習(十六) 公用元件之 獲取欄位label資訊

salesforce lightning零基礎學習(十六) 公用元件之 獲取欄位label資訊

我們做的專案好多都是多語言的專案,針對不同國家需要展示不同的語言的標題。我們在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的公用元件的實現。篇中有錯誤的地方歡迎指出,有不懂的歡迎留言,有可以優化的地方歡迎交流並且鼓勵優化。

&n