Data Tableを使った疑似的なツリー構造


元の質問 : [ow to Display a tree structure of related contacts with their accounts in an Aura Component datatable](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000IPWmySAH)

あんまり見栄えはよくないですが、仕様通りに作ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/509273c7-3197-7093-f21c-0005246df90a.png)


**Apex controller**

```
public with sharing class ReferralProgramApexController {
    @AuraEnabled
    public static List<Map<String,Object>> getNestedAccounts() {
        List<Map<String,Object>> myDataList = new List<Map<String,Object>>();
        
        List<Account> AccountsContactsNestedList = [SELECT Id, Name,
                                    (SELECT Id, Email, phone From Contacts)
                                    FROM Account Limit 3];
        
        for (Account myObj : AccountsContactsNestedList) {        	
            
            Integer i = 0;
            for (Contact con : myObj.Contacts){
                if ( i == 0) {
                    Map<String, Object> myMap = new Map<String, Object>();
                    myMap.put('accRecord.Id',myObj.Id); 
            		myMap.put('accRecord.Name',myObj.Name);
                    
                    myMap.put('contactList.Email',con.Email); 
                    myMap.put('contactList.Phone',con.Phone);
                    myDataList.add(myMap);
                } else {
                    Map<String, Object> myMap = new Map<String, Object>();
                    myMap.put('accRecord.Id',null); 
            		myMap.put('accRecord.Name',null);  
                    myMap.put('contactList.Email',con.Email); 
                    myMap.put('contactList.Phone',con.Phone);
                    myDataList.add(myMap);
                }
                i = i + 1;
            }           
        }
        
        return myDataList;
    }
}
```

**コンポーネント**

```
<aura:component controller = "ReferralProgramApexController"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >

    <aura:attribute name="AccountNestedList" type="object[]"/>
    <aura:attribute name="columns" type="List"/>

    <aura:handler name="init" action="{!c.FetchData}" value="{!this}"/>

    <aura:if isTrue="{!not(empty(v.AccountNestedList))}">
         <lightning:datatable data="{!v.AccountNestedList}" 
                         columns="{!v.columns}" 
                         keyField="Id"
                         hideCheckboxColumn="true"/>
      
      <!--  <aura:iteration items="{!v.AccountNestedList}" var="obj" indexVar="sNo"> 
                 {!obj.accRecord.Name}
            <aura:iteration items="{!obj.contactList}" var="cont"> 
                {!cont.Email} {!cont.Phone}
            </aura:iteration> 
        </aura:iteration>         
        -->
     <aura:set attribute="else">
                <div Style="text-align : center"> " There are no contacts " </div>
            </aura:set>
     </aura:if>
</aura:component>
```

```
({
    // Load Accounts from Salesforce
    FetchData: function(component, event, helper) {
        //**********set the datatable according to the data to be fetched
        component.set('v.columns', [
            {label: 'Account Id', fieldName: 'accRecord.Id', type: 'text' },
            {label: 'Name', fieldName: 'accRecord.Name', type: 'text' },
            {label: 'Email', fieldName: 'contactList.Email', type: 'text' },
            {label: 'Phone', fieldName: 'contactList.Phone', type: 'text' }
        ]);
        helper.getData(component);
    }
  
})
```

```
({
	getData : function(component) {
        // Create a remote method call (Action) from apex controller
        let action = component.get("c.getNestedAccounts");
        // Add callback behavior for when response is received
        action.setCallback(this, function(response) {
            let state = response.getState();
            if (state === "SUCCESS") {
                //set the component accountlList attribute with fetched data
                component.set("v.AccountNestedList", response.getReturnValue());                   
            }
            else {
                console.log("Failed with state: " + state);
            }
        });
        // Send action off to be executed
        $A.enqueueAction(action);
    }
})
```