Strona internetowa CRUD w Delphi w pięć minut

· Komponenty
Strona internetowa CRUD w Delphi w pięć minut

Każda aplikacja biznesowa zawiera tę samą stronę, pisaną od nowa dla każdej tabeli: listę z polem wyszukiwania i stronicowaniem, formularz do tworzenia i edycji, potwierdzenie usunięcia oraz kod, który zapisuje. Nasze własne demo administracyjne miało cztery uchwyty żądań i około czterystu linii budowniczych stron tylko dla klientów, a potem to samo jeszcze raz dla dostawców i jeszcze raz dla faktur.

sgcWebSockets 2026.10 dodaje TsgcHTMLComponent_CRUD, który przejmuje tę stronę. Demo buduje teraz sekcję klientów za pomocą adaptera złożonego z sześciu metod i trzyma obok niej wersję napisaną ręcznie, żebyś mógł porównać obie.

Strona

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;

Podpięty do zbioru danych, sam odczytuje swoje kolumny, i to jest cała strona: lista, wyszukiwanie, stronicowanie, formularz tworzenia i edycji, potwierdzenie usunięcia oraz eksport CSV tego, co aktualnie pokazuje lista.

Albo własny SQL

Zbiór danych to jeden ze sposobów przechowywania rekordów, nie jedyny. Wszystko, co zmienia rekord, przechodzi przez adapter, więc komponent nigdy nie widzi SQL, rekordu ani sterownika bazy danych:

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));

Sześć metod nad tym, co już masz. W demie każda z nich to pojedyncze wywołanie na puli bazy danych aplikacji.

Elementy, które i tak musiałbyś dopisać

Blokada optymistyczna. Wskaż kolumnę wersji, a zapis porówna to, co wysyła przeglądarka, z tym, co jest zapisane, dzięki czemu druga osoba, która naciśnie Zapisz, zostanie poinformowana, że rekord się zmienił, zamiast po cichu nadpisać pierwszy zapis:

FCRUD.VersionField := 'UPDATED_AT';

Nagłówek i pozycje. Listy podrzędne rekordu to inne komponenty CRUD, renderowane pod formularzem podczas edycji rekordu:

with FCRUD.Details.Add do
begin
  CRUD := FCRUDOrderLines;
  MasterField := 'ORDER_ID';
  Caption := 'Lines';
end;

Walidacja dotycząca Twoich danych, a nie formularzy. Wymagane kolumny to zadanie komponentu; OnValidate to miejsce, gdzie żyją reguły dotyczące klientów. Dodaj jedną linię na każdy problem, a zapis zostanie odrzucony, a formularz wróci razem z nimi.

Dwa sposoby na start

W IDE jest teraz kreator: Tools › New sgcHTML CRUD page. Podaj nazwę tabeli, klucz i kolumny, a komponent zostanie utworzony na projektowanym formularzu, z dwiema liniami, które go podłączają, gotowymi w schowku.

Poza IDE jest narzędzie wiersza poleceń, sgcHTMLGen, które zapisuje kod źródłowy strony w Object Pascal albo w C#:

sgcHTMLGen crud --table Customers --prefix /customers ^
  --fields "ID:key CODE:req:32 NAME:req:120 CITY:80 NOTES:noform"

Jak strona odpowiada

Każdy element sterujący strony wysyła dane w ten sam sposób: pole wyszukiwania, przycisk Nowy, Edytuj i Usuń wiersza oraz sam formularz niosą trzy ukryte pola, action, crud oraz, tam gdzie ma to znaczenie, key. Host je odczytuje i wywołuje ProcessAction, które zwraca znaczniki do podmiany.

Wiadomość wysłana przez gniazdo nie niesie żadnej ścieżki, więc nigdy nie trafia do routera i nigdy nie przechodzi jego własnej kontroli. Autoryzacja jest zadaniem aplikacji, a silnik daje teraz do tego wszystko, co potrzebne:

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;

Klucz, który przychodzi z przeglądarki, jest wyszukiwany metodą Locate przed uruchomieniem jakiegokolwiek zapisu, więc klucz, który do nikogo nie należy, niczego nie zapisuje.

Zobacz obie wersje

W Demos\60.HTML\01.RunTime\02.AdminCRUD, /customers to komponent, a /customers-classic to strona, którą zastąpił. Ta sama baza danych, te same dane, ten sam wygląd. Jedna z nich jest o czterysta linii krótsza.

Aktualizacja

Komponent jest częścią sgcHTML i ma charakter addytywny: nic się nie zmienia na istniejącej stronie, dopóki nie upuścisz go na formularzu.

Czytaj dalej

Zobacz wideo

Jest na ten temat krótkie wideo na kanale eSeGeCe.

Pytania, uwagi lub pomoc przy migracji? Skontaktuj się z nami — otrzymasz odpowiedź od osób, które napisały ten kod.