sgcHTML'i değerlendiren kişilerden sık duyduğumuz bir soru: birçok hazır bileşenle birlikte geliyor, ama ya zaten beğendiğim bir JavaScript kütüphanem varsa? Belki D3.js veya Chart.js'ten grafikleri tercih ediyorsunuz, ya da bir DevExtreme Grid için ödeme yaptınız ve onu kullanmak istiyorsunuz. Kısa cevap, sgcHTML'in açık olacak şekilde tasarlanmış olmasıdır. Delphi, C++Builder veya .NET kodundan sunucuda tam sayfalar üretir ve tarayıcıda çalışan herhangi bir kütüphane üç küçük kanca ile eklenir. Aynı kütüphaneyi sık sık kullanıyorsanız, onu yeniden kullanılabilir bir bileşende sarmalayabilirsiniz, böylece uygulamanızın geri kalanı JavaScript'i hiç görmez.
Üç kanca
Her üçüncü taraf bileşeni sayfada aynı üç şeye ihtiyaç duyar: kütüphanenin yüklenmesi gerekir, içine oluşturma yapacağı bir öğe bulunmalıdır ve DOM hazır olduğunda çalışacak bir init kodu satırı gerekir. TsgcHTMLComponent_Site bileşeni her biri için size bir özellik veya yöntem sunar.
CustomHead, kütüphaneyi yükleyen bir<script>veya<link>için doğal yer olan<head>içine markup ekler.AddContent, hedef öğeyi sayfa gövdesine yerleştirir.BodyEndHTML, kütüphane yüklendikten sonra,</body>etiketinden hemen önce init kodunuzu çalıştırır.
İşte eksiksiz bir D3.js örneği. Kütüphaneyi yükleyin, bir kapsayıcı ekleyin, ardından D3'ün içine çizim yapmasına izin verin.
uses
sgcHTML_Component_Site;
var
oSite: TsgcHTMLComponent_Site;
begin
oSite := TsgcHTMLComponent_Site.Create(nil);
try
oSite.Title := 'Sales Dashboard';
// 1) Load the library (a public CDN, or a file you serve yourself)
oSite.CustomHead := '<script src="https://d3js.org/d3.v7.min.js"></script>';
// 2) Emit the element your library renders into
oSite.AddContent('<div id="chart"></div>');
// 3) Run your init code at the end of the body
oSite.BodyEndHTML :=
'<script>' +
' const data = [4, 8, 15, 16, 23, 42];' +
' d3.select("#chart").selectAll("div").data(data).enter()' +
' .append("div").attr("class", "bar")' +
' .style("width", d => (d * 12) + "px").text(d => d);' +
'</script>';
WebModule.Response := oSite.HTML;
finally
oSite.Free;
end;
end;
İşte kalıbın tamamı bu. URL'yi ve init kodunu değiştirin, aynı üç satır Chart.js'i, bir DevExtreme bileşenini, bir takvimi, bir haritayı veya başka herhangi bir şeyi taşır.
CDN veya kendi sunucunuzda barındırma
Yukarıdaki örnek, bir şeyi denemenin en hızlı yolu olan genel bir CDN'ye işaret ediyor. Bir intranet uygulaması, çevrimdışı bir dağıtım için veya belirli bir sürümü sabitlemek istediğinizde, kütüphane dosyasını sgc sunucusundan kendiniz sunun ve yerel bir yol ile referans verin. Birkaç yerleşik bileşen bunu zaten yapıyor: paket halindeki Chart bileşeni, Chart.js'i bir CDN yerine yerel bir /chart.umd.min.js dosyasından yükler, böylece sayfanın dışa dönük hiçbir bağımlılığı olmaz.
// The .js and .css files sit next to your server executable and are
// served as static files, so the page references them by local path:
oSite.CustomHead :=
'<link rel="stylesheet" href="/assets/mylib.min.css">' +
'<script src="/assets/mylib.min.js"></script>';
Head kısmını ham bir string yerine node'lar olarak oluşturmayı tercih ederseniz, şablon katmanı AddScript ve AddStylesheet yardımcılarıyla birlikte HeadNodes ve BodyEndNodes listelerini, ayrıca TsgcHTMLScript (Src, Code, Defer, Async ile) ve TsgcHTMLStylesheet node'larını sunar. Ham stringler ile tipli node'lar birbirinin yerine kullanılabilir, kodunuzda hangisi daha okunaklıysa onu kullanın.
Birkaç satırda Chart.js
Chart.js sık istenen bir kütüphane, o yüzden işte aynı üç kanca üzerinden kullanımı. Kütüphaneyi yükleyin, bir <canvas> yerleştirin, ardından grafiği oluşturun.
oSite.CustomHead := '<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>';
oSite.AddContent('<canvas id="revenue" width="600" height="300"></canvas>');
oSite.BodyEndHTML :=
'<script>' +
' new Chart(document.getElementById("revenue"), {' +
' type: "bar",' +
' data: {' +
' labels: ["Q1", "Q2", "Q3", "Q4"],' +
' datasets: [{ label: "Revenue", data: [12, 19, 7, 15] }]' +
' }' +
' });' +
'</script>';
Yalnızca grafik istiyorsanız ve belirli bir kütüphaneye ihtiyacınız yoksa, sgcHTML'in sizin için zaten bağlanmış Chart.js olan bir TsgcHTMLComponent_Chart bileşeni sunduğunu, herhangi bir ham Chart.js yapılandırmasını doğrudan geçiren bir CustomOptions özelliğiyle birlikte geldiğini unutmayın. Bu bölüm, kütüphaneyi kendiniz yönetmek istediğiniz durumlar içindir.
Bir DevExtreme Grid
DevExtreme, daha ağır bir ticari paket için iyi bir örnektir. DataGrid'in stil sayfasının ve paketinin yüklenmesine, bağlanacağı bir öğeye ve bir yapılandırma nesnesine ihtiyacı vardır. Yaklaşımda hiçbir şey değişmez.
oSite.CustomHead :=
'<link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/23.2.3/css/dx.light.css">' +
'<script src="https://cdn3.devexpress.com/jslib/23.2.3/js/dx.all.js"></script>';
oSite.AddContent('<div id="grid"></div>');
oSite.BodyEndHTML :=
'<script>' +
' new DevExpress.ui.dxDataGrid(document.getElementById("grid"), {' +
' dataSource: [' +
' { id: 1, name: "Widget", price: 9.90 },' +
' { id: 2, name: "Gadget", price: 14.50 }' +
' ],' +
' columns: ["id", "name", "price"],' +
' showBorders: true' +
' });' +
'</script>';
İlginç kısım, dataSource'un nereden geldiğidir. Bir veri kümesini sunucuda JSON'a serileştirip gösterildiği gibi satır içi ekleyebilir, ya da grid'i sgc sunucunuzun sunduğu bir uç noktaya yönlendirip canlı olarak yüklemesine izin verebilirsiniz. Demos klasöründe, bir grid'i bir sgc WebSocket sunucusundan besleyen hazır bir DevExtreme Grid örneği bulunur, böylece veriler sayfa yeniden yüklenmeden gerçek zamanlı olarak güncellenir.
Yeniden kullanılabilir bir bileşende sarmalayın
Tek seferlik bir kullanım için ham stringleri dolaştırmak sorun değildir. Aynı kütüphaneyi sayfa sayfa kullandığınızı fark ederseniz, onu bir bileşene yükseltin: TsgcHTMLComponent'ten türetin ve kendi markup'ınızı artı kütüphane bağlantı kodunu döndürmek için GetHTML'yi override edin. Uygulamanızın geri kalanında ise, tıpkı yerleşik bir bileşende olduğu gibi, yalnızca bir özellik ayarlar ve HTML'yi çağırırsınız.
uses
sgcHTML_Component;
type
TsgcHTMLComponent_D3Bars = class(TsgcHTMLComponent)
private
FData: string; // a JSON array, e.g. '[4,8,15,16,23,42]'
published
property Data: string read FData write FData;
public
function GetHTML: string; override;
end;
function TsgcHTMLComponent_D3Bars.GetHTML: string;
begin
Result :=
'<div id="d3bars"></div>' +
'<script src="https://d3js.org/d3.v7.min.js"></script>' +
'<script>' +
' const data = ' + FData + ';' +
' d3.select("#d3bars").selectAll("span").data(data).enter()' +
' .append("span").style("padding-right", d => d + "px").text(d => d);' +
'</script>';
end;
Bu özel bir durum değildir, gönderilen bileşenlerin birçoğu tam olarak bu şekilde inşa edilmiştir. Map bileşeni Leaflet'i, RichEditor Quill'i, KanbanBoard SortableJS'i ve PDFViewer pdf.js'i sarmalar; her biri kendi kütüphanesini yükler ve init kodunu tam olarak bu kancalar aracılığıyla yayar. Kendi sarmalayıcınız da onların yanında birinci sınıf bir bileşen olarak yer alır ve kütüphane stillere ihtiyaç duyuyorsa, sgcHTML'in sayfa genelinde sizin için topladığı ve tekrarları kaldırdığı eşleşen bir GetCSS override'ı ekleyebilirsiniz.
Deneyin
Çıkarılacak sonuç, sgcHTML'in sizi asla sınırlamamasıdır. Yerleşik bileşenler geniş bir alanı kapsar, ve belirli bir şeye ihtiyacınız olduğunda, D3.js, Chart.js, bir DevExtreme Grid veya Chart, hangi tarayıcı kütüphanesi olursa olsun, gömmek için üç kanca ve yeniden kullanılabilir hale getirmek için küçük bir alt sınıf yeterlidir.
Sorularınız veya geri bildiriminiz mi var? Bizimle iletişime geçin, kodu yazan kişilerden bir yanıt alacaksınız.
