0

我正在开发一个闪电组件,它将显示一个自定义的、动态的、“相关”记录列表,可用于在一个对象的列表中显示相关记录,该对象也是同一个父对象的子对象。因此,例如,如果客户是父记录,并且自定义对象 1 和自定义对象 2 都是该客户的子级,我想在自定义对象 2 闪电记录页面。我在 LC 画布和字段集中使用用户输入来分别定位记录和显示列。

我创建的组件可以动态查询和显示记录、列和字段值。我还想使用“名称”字段包含指向自定义对象 1 记录的可点击链接。但是,我似乎无法动态设置 Name 字段的 typeAttribute 以显示记录的标签。因为我将它分配为列标题的属性,所以它只取数组中的最后一个值。

有没有办法将 typeAttribute 分配给记录响应,而不是列标题响应?

这是我的代码:

顶点类:

公共类 DynamicRelatedListController {

@AuraEnabled
    public static String fetchParent(String recId, String parentLookup, String objPageName) {
        
       
        String strSOQL = 'SELECT Id, ' + parentLookup + ' FROM ' + objPageName + ' WHERE Id = \'' + recId + '\' LIMIT 1 ' ;  

       List <SObject> currentRecord = new List <SObject>(Database.query(strSOQL)); 
        
        system.debug('Database Result for fetch parent ' + strSOQL);
        
        List <String> parentIds = new List<String>();
        
        for(SObject cr : currentRecord) {
           
           parentIds.add(String.valueOf(cr.get(parentLookup)));

        }

       
         String parentId = parentIds[0];
        
        return parentId;

    }


    @AuraEnabled
    public static List < SObject > fetchChildren(String objectName, String criteria, String parentFieldAPIName, String recId, String parentLookup, String objPageName) {

        String parentId = fetchParent(recId, parentLookup, objPageName);

        // String prefix ='%' + GM_Util.findObjectNameFromRecordIdPrefix(parentId) + '%';
        
        List < SObject > childRecordList = new List < SObject > ();
        String strSOQL = 'SELECT Id, ' + parentFieldAPIName + ' FROM ' + objectName + ' WHERE ' + parentFieldAPIName + ' = \'' + parentId  + '\'';  

        if ( String.isNotBlank( criteria ) )  
            strSOQL += ' ' + criteria;  
     

        childRecordList = Database.query(strSOQL);
        
        system.debug('Database Result for fetch children ' + strSOQL);

        return childRecordList;

    }

   

    @AuraEnabled
    public static DataTableDetails fetchRelatedRecs(String recId, String fieldSetName, String criteria, String objectName, String parentFieldAPIName, String objPageName, String parentLookup)
        {  
            
      
            DataTableDetails dataTableDtls = new DataTableDetails();
            List<GM_Util_Aura.FieldSetMemberWrapperClass> listOfFieldSetMembers = new List<GM_Util_Aura.FieldSetMemberWrapperClass>();
            if(fieldSetName != NULL && fieldSetName != ''){
                listOfFieldSetMembers = GM_Util_Aura.getFieldSetMemberJSON(objectName, fieldSetName);                
            }
            // List<GM_Util_Aura.FieldSetMemberWrapperClass> listOfFieldSetMembers = GM_Util_Aura.getFieldSetMemberJSON(objectName, fieldSetName);
            List<String> WHERE_IN_LIST = new List <String>();

            for (SObject crl: fetchChildren(objectName, criteria, parentFieldAPIName, recId, parentLookup, objPageName)) {

                WHERE_IN_LIST.add(crl.Id);
            }   
            
            String SQL = 'SELECT Id ';
            if(listOfFieldSetMembers != null && listOfFieldSetMembers.size() > 0){
                for(GM_Util_Aura.FieldSetMemberWrapperClass fsmwc : listOfFieldSetMembers){
                    dataTableDtls.fieldLabelsList.add(fsmwc);
                    
                    SQL = SQL + ',' +  fsmwc.fieldName;
                }
            }
            SQL += ' FROM ' + objectName +' WHERE Id IN : WHERE_IN_LIST' ;
            System.debug('final SQL statement (WHERE_IN_LIST): ' + SQL);
            
            dataTableDtls.returnedParentRecords = Database.query(SQL);
            System.debug('returned Parent Records are ' + Database.Query(SQL));

            
            
            // filteredResults = Database.query(SQL); 
            
            System.debug('final filtered results are: ' + dataTableDtls);
            
            System.debug('returned field labels are ' + listOfFieldSetMembers);

            return dataTableDtls;        
        }


        
        public class DataTableDetails{
            @AuraEnabled
            public List<sObject> returnedParentRecords = new List<sObject>();
            @AuraEnabled
            public List<GM_Util_Aura.FieldSetMemberWrapperClass> fieldLabelsList = new List<GM_Util_Aura.FieldSetMemberWrapperClass>();
        }
    }

我的组件助手和 cmp 代码:

({

    getDataTable: function(component, event) {
    
        console.log("entered Get Data Table");
    
        var action = component.get("c.fetchRelatedRecs");
        action.setParams({
            recId: component.get("v.recordId"),
            objectName: component.get("v.ObjectAPIName"),
            fieldSetName: component.get("v.FieldSetAPIName"),
            objPageName: component.get("v.sObjectName"), 
            parentFieldAPIName: component.get("v.ParentFieldAPIName"),
            parentLookup: component.get("v.ParentFieldLookupName"),
            criteria: component.get("v.criteria")
        });
        action.setCallback(this, function(response){
            //console.log("this is the fieldSetName " + fieldSetName)
            var state = response.getState();
            if(state === 'SUCCESS'){
    
                var fieldSetResponse = response.getReturnValue().fieldLabelsList;
                var parentRecordsResponse = response.getReturnValue().returnedParentRecords;
    
                console.log("Parent records length " + parentRecordsResponse.length);
                console.log("Field Set Length " + fieldSetResponse.length);
                console.log("here are the field labels before data transformation " + JSON.stringify(fieldSetResponse));
                console.log("Here are all the related records before transformation " + JSON.stringify(parentRecordsResponse));
    
                
                //this for loop changes all lookup fields to type 'url' for clickable links
                for(var i = 0; i < parentRecordsResponse.length; i++ ) {
 
                    
                    if(fieldSetResponse[i].fieldName.includes('__r.Name')) {
                        fieldSetResponse[i].type ='url';

                        //drop the .Name from the lookup field so that the lightning:datatable can find the field value in the parentRecordsResponse object 
                        fieldSetResponse[i].fieldName = fieldSetResponse[i].fieldName.replace('.Name', '') ;
    
                            //this for loop locates the key in the parentRecordsResponse object that matches the lookup field in the fieldSetResponse object. 
                           for(var j = 0; j < parentRecordsResponse.length; j++) {
                            var arraykeys = Object.keys(parentRecordsResponse[j]);
                            var arrayvalues = Object.values(parentRecordsResponse[j]);
                               
                               console.log("Array Keys in iteration "+ arraykeys[j]);
                               console.log("Array Values " + JSON.stringify(arrayvalues));

    
                            //this for loop locates the key in the parentRecordsResponse object that matches the lookup field in the fieldSetResponse object. 
                             for(var h = 0; h <arraykeys.length; h++) {
                                 
                                 console.log("Array Keys in iteration h "+ arraykeys[h]);
                                 
                                 //fieldSetResponse[i]['typeAttributes'] = {label: arrayvalues[h].Name };
                                 
                                 if(fieldSetResponse[i].fieldName === arraykeys[h]){
                                     
                                     
                                
                                     //assign the'type attributes' to the url field with the Name value of the lookup field
                                     fieldSetResponse[i]['typeAttributes'] = {label: arrayvalues[h]['Name'] };
                                       
                                        //transform the nested lookup field object to /recordId for the url
                                     parentRecordsResponse[j][arraykeys[h]] = "/" + arrayvalues[h].Id ;

    
                                 }
                             }
    
                        }
    
                    } 
                }
    
                    console.log("here are the field labels after data transformation " + JSON.stringify(fieldSetResponse));
                    console.log("Here are all the related records " + JSON.stringify(parentRecordsResponse));
    
                    //send the responses back to the controller and set them using the 'v.' keys
                    component.set("v.columnsHeader", fieldSetResponse);
                    component.set("v.listofRelatedRecords", parentRecordsResponse); 
            }
    
                else if (state === 'ERROR'){
                console.log('::::::::::::: ERROR :::::::::::::');
            }
        });
        $A.enqueueAction(action);
    }
    
    
    })
<aura:component controller="DynamicRelatedListController" implements="flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction,force:hasSObjectName" access="global">

    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="ObjectAPIName" type="String"/>
    <aura:attribute name="FieldSetAPIName" type="String"/>
    <aura:attribute name="ParentFieldAPIName" type="String"/>
    <aura:attribute name="ParentFieldLookupName" type="String"/>
    <aura:attribute name="Criteria" type="String"/>
    <aura:attribute name="TableName" type="String"/>
    <!-- <aura:attribute name="recordId" type="String" /> -->
    <aura:attribute name="columnsHeader" type="List"/>
    <aura:attribute name="listofRelatedRecords" type="Object"/>


    <lightning:card aura:id="lightCard" class="slds-card_boundary" title="{!v.TableName}" iconName="standard:file">    
        <div style="overflow-x: auto;">
            <lightning:datatable data="{!v.listofRelatedRecords}"
            columns="{!v.columnsHeader}"
            keyField="Id"
            hideCheckboxColumn="true"/>  
        </div>
    </lightning:card> 
</aura:component>

这就是最终结果的样子——注意所有的值都是不同的,除了名称字段的标签。该链接本身工作正常,并导航到相应的记录:

闪电组件用户界面

4

1 回答 1

0

我想到了。在基本层面上,这一行缺少“fieldName”属性,该属性采用字段名称的 API 并应用值。

所以这个: fieldSetResponse[i]['typeAttributes'] = {label: arrayvalues[h]['Name'] }; 应该是这样的: fieldSetResponse[i]['typeAttributes'] = {label: fieldName: {API NAME OF FIELD THOLDS THE DISPLAY VALUE} };

即使这样,也无法动态执行此操作,因为在这种情况下,当 fieldName 是查找字段本身时,它会显示记录 Id。我可以传递一个硬编码的 API 名称,但显然这会破坏目的。

为了解决这个问题,我添加了一个通用标签(单击以查看记录)并在该目标对象上创建了一个公式字段,该字段提取父记录名称并将其添加到我的字段集中。

更新组件的图片

这是一个已知问题:https ://trailblazer.salesforce.com/ideaView?id=0873A000000lLXYQA2 这可以通过创建扁平化函数来处理(尽管我还没有尝试实现):https://developer。 salesforce.com/forums/?id=9062I000000XtwnQAC

于 2020-10-28T13:08:09.567 回答