我正在开发一个闪电组件,它将显示一个自定义的、动态的、“相关”记录列表,可用于在一个对象的列表中显示相关记录,该对象也是同一个父对象的子对象。因此,例如,如果客户是父记录,并且自定义对象 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>
这就是最终结果的样子——注意所有的值都是不同的,除了名称字段的标签。该链接本身工作正常,并导航到相应的记录: