Ogni applicazione aziendale contiene la stessa pagina, riscritta di volta in volta per ogni tabella: un elenco con una casella di ricerca e un paginatore, un modulo per creare e modificare, una conferma per eliminare, e il codice che scrive. La nostra demo di amministrazione aveva quattro gestori di richieste e circa quattrocento righe di costruttori di pagine solo per i clienti, e poi di nuovo le stesse per i fornitori, e ancora per le fatture.
sgcWebSockets 2026.10 aggiunge TsgcHTMLComponent_CRUD, che possiede quella pagina. La demo ora costruisce l'area clienti con un adapter di sei metodi, e mantiene accanto la versione scritta a mano così puoi leggerle entrambe.
La pagina
uses
sgcHTML_Component_CRUD;
FCRUD := TsgcHTMLComponent_CRUD.Create(Self);
FCRUD.CRUDID := 'customers';
FCRUD.RoutePrefix := '/customers';
FCRUD.Title := 'Customers';
FCRUD.KeyField := 'ID';
FCRUD.PageSize := 15;
FCRUD.Actions := [caCreate, caEdit, caDelete, caView, caExport];
FCRUD.DataSet := FDQueryCustomers;
Collegato a un dataset legge da solo le proprie colonne, ed è l'intera pagina: elenco, ricerca, paginazione, il modulo di creazione e modifica, la conferma di eliminazione e un'esportazione CSV di ciò che l'elenco sta mostrando.
Oppure il tuo SQL
Un dataset è un modo per memorizzare i record, non l'unico. Tutto ciò che modifica un record passa attraverso un adapter, così il componente non vede mai SQL, un record o un driver di database:
type
TCustomersAdapter = class(TsgcHTMLCRUDAdapter)
public
function Locate(const aKey: string): Boolean; override;
function Read(const aKey: string; aValues: TStrings): Boolean; override;
function List(const aSearch: string; aPage, aPageSize: Integer;
aRows: TStrings): Integer; override;
function Insert(aValues: TStrings; var aKey: string;
aErrors: TStrings): Boolean; override;
function Update(const aKey: string; aValues, aErrors: TStrings)
: Boolean; override;
function Delete(const aKey: string; aErrors: TStrings): Boolean; override;
end;
FCRUD.SetAdapter(TCustomersAdapter.Create(FCRUD));
Sei metodi sopra qualsiasi cosa tu abbia già. Nella demo ciascuno è una singola chiamata sul pool di database dell'applicazione.
Le parti che avresti scritto dopo
Blocco ottimistico. Indica una colonna di versione e un salvataggio confronta ciò che il browser invia con ciò che è memorizzato, così alla seconda persona che preme Salva viene detto che il record è cambiato invece di sovrascrivere silenziosamente la prima:
FCRUD.VersionField := 'UPDATED_AT';
Master e dettaglio. Gli elenchi figli di un record sono altri componenti CRUD, visualizzati sotto il modulo mentre il record viene modificato:
with FCRUD.Details.Add do
begin
CRUD := FCRUDOrderLines;
MasterField := 'ORDER_ID';
Caption := 'Lines';
end;
Convalida che riguarda i tuoi dati, non i moduli. Le colonne obbligatorie sono compito del componente; OnValidate è dove vivono le regole che riguardano i clienti. Aggiungi una riga per ogni problema e la scrittura viene rifiutata e il modulo torna indietro con quelle righe.
Due modi per iniziare
Nell'IDE ora c'è una procedura guidata: Tools › New sgcHTML CRUD page. Indica la tabella, la chiave e le colonne, e il componente viene creato sul form in fase di progettazione, con le due righe che lo collegano già negli appunti.
Al di fuori dell'IDE c'è uno strumento a riga di comando, sgcHTMLGen, che scrive il sorgente della pagina in Object Pascal o in C#:
sgcHTMLGen crud --table Customers --prefix /customers ^
--fields "ID:key CODE:req:32 NAME:req:120 CITY:80 NOTES:noform"
Come la pagina risponde
Ogni controllo della pagina invia i dati nello stesso modo: la casella di ricerca, il pulsante New, l'Edit e il Delete di una riga, e il modulo stesso, portano tre campi nascosti, action, crud e, dove ha un significato, key. L'host li legge e chiama ProcessAction, che restituisce il markup da inserire al loro posto.
Un messaggio inviato sul socket non porta alcun percorso, quindi non raggiunge mai il router e non riceve mai il controllo proprio del router. Autorizzarlo è compito dell'applicazione, e il motore ora ti fornisce ciò che serve:
oSession := FHTMXEngine.MessageSession(aConnection, FAuth);
try
if not Assigned(oSession) then
Exit; // a write with nobody behind it is not a write
oPage.ProcessAction(vAction, oParams.Values['key'], oParams, aResponse);
finally
oSession.Free;
end;
La chiave che arriva dal browser viene cercata con Locate prima che venga eseguita qualsiasi scrittura, così una chiave che non appartiene a nessuno non scrive nulla.
Guarda entrambe le versioni
In Demos\60.HTML\01.RunTime\02.AdminCRUD, /customers è il componente e /customers-classic è la pagina che ha sostituito. Stesso database, stessi dati, stesso aspetto. Una delle due è più corta di quattrocento righe.
Aggiornamento
Il componente fa parte di sgcHTML ed è additivo: nulla cambia in una pagina esistente finché non ne trascini uno su un form.
Continua a leggere
- Fai una domanda alla tua grid Delphi in inglese semplice
- Raggiungi un browser chiuso, da Delphi
- sgcWebSockets 2026.10, tutto il resto di questa versione
Guardalo in video
C'è un breve video su questo sul canale eSeGeCe.
Domande, feedback o aiuto per la migrazione? Mettiti in contatto — riceverai una risposta dalle persone che hanno scritto il codice.
