Lightning Web Component実験

まず、Lightning Web Componentの基本については、下記Trailheadで学習できます
https://trailhead.salesforce.com/ja/content/learn/trails/build-lightning-web-components

ためしに、サッカーチーム選手一覧を表示するサンプルを作ってみました
フォルダ構成
lwc
├classes
│├SquadController.cls
│└SquadController.cls-meta.xml
└squadList
  ├squadList.html
  ├squadList.js
  └squadList.js-meta.xml

Apexコントローラー　SquadController.cls　カスタムオブジェクトSquad__cから選手一覧を取得
public with sharing class SquadController {
    @AuraEnabled(cacheable=true)
    public static List<Squad__c> getSquads(){
        return [
            SELECT Id, Name, BackNumber__c, FullName__c, Position__c, Nationality__c, Height__c, Weight__c
            FROM Squad__c
            ORDER BY BackNumber__c
        ];
    }
}

HTMLテンプレート squadList.html
<template>
    <lightning-card>
        <template if:true={squads.data}>
            <lightning-datatable
                key-field="Id"
                data={squads.data}
                columns={columns}
                onsave={handleSave}
                onrowselection={handleRowSelection}
                draft-values={draftValues}
            >
           </lightning-datatable>
           <template if:true={squads.error}>
            <!-- handle Apex error -->
           </template>
        </template>
    </lightning-card>
</template>

JSファイル　squadList.js

import { LightningElement, wire, api} from 'lwc';
import getSquads from '@salesforce/apex/SquadController.getSquads';
import { refreshApex } from '@salesforce/apex';
import { updateRecord } from 'lightning/uiRecordApi';

import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import BACKNUMBER_FIELD from '@salesforce/schema/Squad__c.BackNumber__c';
import FULLNAME_FIELD from '@salesforce/schema/Squad__c.FullName__c';
import POSITION_FIELD from '@salesforce/schema/Squad__c.Position__c';
import NATIONALITY_FIELD from '@salesforce/schema/Squad__c.Nationality__c';
import ID_FIELD from '@salesforce/schema/Squad__c.Id';

const COLUMNS = [
    { label: 'BackNumber', fieldName: BACKNUMBER_FIELD.fieldApiName, type: 'text', editable: true },
    { label: 'FullName', fieldName: FULLNAME_FIELD.fieldApiName, type: 'text', editable: true },
    { label: 'Position', fieldName: POSITION_FIELD.fieldApiName, type: 'text', editable: true },
    { label: 'Nationality', fieldName: NATIONALITY_FIELD.fieldApiName, type: 'text', editable: true },
    { label: 'Id', fieldName: ID_FIELD.fieldApiName, type: 'text' }
];
export default class SquadList extends LightningElement {
    columns = COLUMNS;
    draftValues = [];

    @wire(getSquads)
    squads;

    handleSave(event) {

        const fields = {}; 
        fields[BACKNUMBER_FIELD.fieldApiName] = event.detail.draftValues[0].BackNumber__c;
        fields[FULLNAME_FIELD.fieldApiName] = event.detail.draftValues[0].FullName__c;
        fields[POSITION_FIELD.fieldApiName] = event.detail.draftValues[0].Position__c;
        fields[NATIONALITY_FIELD.fieldApiName] = event.detail.draftValues[0].Nationality__c;
        fields[ID_FIELD.fieldApiName] = event.detail.draftValues[0].Id;

        const recordInput = {fields};

        updateRecord(recordInput)
        .then(() => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: 'Squad__c updated',
                    variant: 'success'
                })
            );
            // Display fresh data in the datatable
            return refreshApex(this.squads).then(() => {

                // Clear all draft values in the datatable
                this.draftValues = [];

            });
        }).catch(error => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error updating or reloading record',
                    message: error.body.message,
                    variant: 'error'
                })
            );
        });
    }

    handleRowSelection(event) {
        this.template.querySelector('lightning-datatable').selectedRows = [];
    }
}