This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Whistle-stop Tour of HTMX Extensions and Using HT MX with ASP.NET Core
Friday, 02 May 2025
Esitys
HTMX on tehokas JavaScript-libraari, joka antaa mahdollisuuden luoda dynaamisia web- sovelluksia vähimmäisJavaScriptin avulla.
En kuitenkaan vieläkään väitä, että minulla olisi asiasta asiantuntemusta. Halusin vain kertoa teille joitakin niistä asioista, jotka olen oppinut tällä tiellä.
Yhteinen artikla: Tässä artiklassa keskitytään HTMX-':n tapahtumajärjestelmään, ,:n laajennusten ja pitkälle kehitettyjen räätälöintien käyttöön..:n käyttö ASP:ssa sekä .:ssä ja NETissä. HTMX ASP:n kanssa.
Tapahtumat
Pyynnön valmistelu
Pyynnön valmisteluvaihe on se, jossa HTMX varmistaa pyynnön ennen kuin se lähetetään serverille.. Tähän sisältyy headerien asettaminen.
flowchart LR
A[htmx:configRequest] --> B[htmx:confirm] --> C[htmx:prompt] --> D[htmx:abort]
Pyyntö elinkaari
Pyynnön elinkaaren vaiheessa HTMX lähettää pyynnön serverille ja käsittelee vastausta. Tämän vaiheen aikana käy ilmi seuraavat tapahtumat
flowchart LR E[htmx:beforeRequest] --> F[htmx:request] --> G[htmx:afterRequest]
Vastauksen käsittely
Vastauksen käsittelyvaihe on, kun HTMX käsittelee vastausta palvelimelta ja päivittää DOMin.
flowchart LR
H[htmx:beforeOnLoad] --> I[htmx:onLoad]
I --> J[htmx:beforeSwap] --> K[htmx:swap] --> L[htmx:afterSwap]
L --> M[htmx:afterSettle] --> N[htmx:afterOnLoad]
Historian hallinta
Historianhallintavaihe on HTMX:n ajantasaistaminen hakukoneen historiasta ja URL:stä. Tämän vaiheen aikana käynnistetään seuraavat tapahtumat
flowchart LR A[htmx:historyRestoreRequest] A --> B[htmx:historyPopped] B --> C[htmx:historyRestorePage]
Kuten näette, HTMX tarjoaa joukon tapahtumia, joihin voi liittyä pyynnön tai vastauksen muuttamiseksi.
Laajennus
Yksi tehokkaimmista HTMX:n näkökohdista on kyky laajentaminen laajentaa toimintavalmiuksiaan. Omassa tapauksessani htmx:configRequest lisätä lisäparametereja pyyntöön. Tämä on hyödyllistä, kun haluatte siirtää lisätietoja palveluun muuttamatta HTML:n tai JavaScriptin koodia
Muut laajennukset saattavat liittyä yhteen htmx:beforeRequest muuttamaan pyyntöä ennen kuin se lähetetään;, mutta sen jälkeen useimmat muut lisäykset, jotka kiinnittävät configRequest; sellaisena kuin beforeRequest asiat, kuten HX-Vals ja HX-Includes on jo liitetty toissijaiseen ( joko maksutaakkaan \ kysymyksenpyynnön stringiin
Voitte jopa kiinnittää htmx:afterSwap toimien toteuttamiseen sen jälkeen, kun sisältö on vaihdettu. Yhdennetty client side templating librariesin kuten Alpine.js tai Liitti voitte luoda tehokkaita dynaamisia sovelluksia vähimmäiskoodin kanssa.
HTMX tarjoaa joitakin rakenteellisia -in lisäyksiä, kuten hx-boost ja hx-swap-oob jotka mahdollistavat HTMX:n toiminnallisuuden parantamisen kirjoittamatta mitään räätälöityä koodia. On kuitenkin tapauksia, joissa on tarpeen luoda omat lisäykset erityistarpeiden täyttämiseksi
Esimerkiksi, saatatte haluta lisätä pyyntöihinne räätälöityjä otsikoita, muuttaa pyynnön maksutaakkaaM SK2 tai käsitellä erityisiä tapahtumia ainutlaatuisella tavalla
Tämän saavuttamiseksi HTMX tarjoaa joustavat integrointipisteet:
{
/**
* init(api)
* Called once when the extension is initialized.
* Use it to set up internal state, store references, or access HTMX utility functions via the api parameter.
*/
init: function(api) {
return null;
},
/**
* getSelectors()
* Returns additional CSS selectors that HTMX should monitor.
* Useful if your extension needs to handle custom elements or dynamic behavior.
*/
getSelectors: function() {
return null;
},
/**
* onEvent(name, evt)
* Called on every HTMX event (e.g., htmx:beforeRequest, htmx:afterSwap).
* Return false to cancel the event or stop propagation.
*/
onEvent: function(name, evt) {
return true;
},
/**
* transformResponse(text, xhr, elt)
* Modify the raw response text before it is parsed and swapped into the DOM.
* Use this to sanitize or preprocess HTML.
*/
transformResponse: function(text, xhr, elt) {
return text;
},
/**
* isInlineSwap(swapStyle)
* Return true if your extension will handle this swap style manually.
* This tells HTMX to skip default behavior.
*/
isInlineSwap: function(swapStyle) {
return false;
},
/**
* handleSwap(swapStyle, target, fragment, settleInfo)
* Perform custom DOM manipulation if you implement a custom swap style.
* Return true to prevent HTMX's default swap.
*/
handleSwap: function(swapStyle, target, fragment, settleInfo) {
return false;
},
/**
* encodeParameters(xhr, parameters, elt)
* Modify or serialize request parameters before sending.
* Return null to use default URL/form encoding.
* Return a string to override with a custom payload (e.g., JSON).
*/
encodeParameters: function(xhr, parameters, elt) {
return null;
}
}
HTMX tarjoaa useita entiseen - -järjestelmään tehtyjä lisäyksiä, joita voi lukekaa siitä täällä.
Esimerkiksi hyödyllinen built-in laajentaminen json-encode sallii JSON-tietojen lähettämisen pyynnön kohdassa URL:n sijasta-encodoitujen lomakkeiden tietojen sijaan . Tämä on hyödyllistä, kun haluatte lähettää monimutkaisia tietorakenteita tai taulukoita palveluun
Voitte nähdä, että tämä liittyy 3 tapahtumiin
init- laajentaminen ja viittauksen säilyttäminen HTMX-API:henonEvent- asettaaContent-Typeheader toapplication/jsonkun pyyntöä konfiguroidaanencodeParameters- ei-todellisen URL:n ylipäätökseen ottamisesta -kodoidun lomakkeen kodifioimisesta ja parametrien serialisoimisesta JSONinaM SK2 Se myös palauttaa stringin, jolla estetään HTMX käyttämästä default-URL:tä-kodoitua lomakettaMSC4
(function() {
let api
htmx.defineExtension('json-enc', {
init: function(apiRef) {
api = apiRef
},
onEvent: function(name, evt) {
if (name === 'htmx:configRequest') {
evt.detail.headers['Content-Type'] = 'application/json'
}
},
encodeParameters: function(xhr, parameters, elt) {
xhr.overrideMimeType('text/json')
const object = {}
parameters.forEach(function(value, key) {
if (Object.hasOwn(object, key)) {
if (!Array.isArray(object[key])) {
object[key] = [object[key]]
}
object[key].push(value)
} else {
object[key] = value
}
})
const vals = api.getExpressionVars(elt)
Object.keys(object).forEach(function(key) {
// FormData encodes values as strings, restore hx-vals/hx-vars with their initial types
object[key] = Object.hasOwn(vals, key) ? vals[key] : object[key]
})
return (JSON.stringify(object))
}
})
})()
Tai jopa yksinkertaisempi, mutta vieläkin käsittävämpi hx-debug lisäys, joka lisää HX-Debug pyynnön otsikko. Tämä on hyödyllinen parannuskeinojen ja logging-tarkoituksiin,, koska se antaa mahdollisuuden nähdä raakapyynnön ja vastauksen tiedot dev-konsolissa
(function() {
htmx.defineExtension('debug', {
onEvent: function(name, evt) {
if (console.debug) {
console.debug(name, evt)
} else if (console) {
console.log('DEBUG:', name, evt)
} else {
throw new Error('NO CONSOLE SUPPORTED')
}
}
})
})()
':ta on paljon enemmän, myös erittäin tehokas Client side templating extension , jonka avulla voidaan käyttää client-välistä templointia käyttäviä kirjastoja muuntamaan palautetut JSON-tiedot HTML:iin. Tämä on hyödyllistä dynaamisten UI:ien luomiseksi ilman, että tarvitsee turvautua serveriin -välin renderoimiseen
Jotkin räätälöityt lisäykset
Dynaamiset Row ID:t
Esimerkiksi äskettäisessä hankkeessa käytin HTMX OOB-vaihtoehtoja, jotta ajantasaistetaan useita riviä taulukossa. Tätä varten halusin tietää, mitkä rivit esitetään tällä hetkellä taulukossa.
Laajentaminen
export default {
encodeParameters: function (xhr, parameters, elt) {
const ext = elt.getAttribute('hx-ext') || '';
if (!ext.split(',').map(e => e.trim()).includes('dynamic-rowids')) {
return null; // Use default behavior
}
const id = elt.dataset.id;
const approve = elt.dataset.approve === 'true';
const minimal = elt.dataset.minimal === 'true';
const single = elt.dataset.single === 'true';
const target = elt.dataset.target;
const payload = { id, approve, minimal, single };
if (approve && target) {
const table = document.querySelector(target);
if (table) {
const rowIds = Array.from(table.querySelectorAll('tr[id^="row-"]'))
.map(row => row.id.replace('row-', ''));
payload.rowIds = rowIds;
}
}
// Merge payload into the parameters object
Object.assign(parameters, payload);
return null; // Return null to continue with default URL-encoded form encoding
}
}
Käyttämällä sitä
Jotta sitä voitaisiin käyttää, meidän on lisättävä HTMX-configurationimme lisäys. Siten omassa lähtökohdassanne js-tiedostossa ( olettaen, että olette käyttämässä mallejaM SK2 teidän pitäisi olla ) voitte tehdä jotain tämänkaltaista
import dynamicRowIds from "./dynamicRowIds"; // Load the file
htmx.defineExtension("dynamic-rowids", dynamicRowIds); // Register the extension
Sitten mihin tahansa elementtiin, jota haluatte käyttää, voitte lisätä hx-ext ominaisuuksia, joiden arvo on dynamic-rowids.
<button
hx-ext="dynamic-rowids"
data-target="#my-table"
data-id="@Model.Id"
data-param1="true"
data-param2="false"
data-param3="@Model.Whatever"
hx-post
hx-controller="Contoller"
hx-action="Action"
>
<i class='bx bx-check text-xl text-white'></i>
</button>
Varmistakaa kohdat
Tämä on toinen yksinkertainen HTMX-lisäys,, joka on tällä kertaa sidottu htmx:configRequest , kun muutamme URL:tä ennen pyynnön lähettämistä. Tämä laajentaminen on hyödyllistä, jos haluatte, että jotkin pyynnöt säilyttävät olemassa olevat filtrit ja toiset eivät
Tämä on samanlainen mutta ei täysin sama kuin nykyinen HTMX-laajennus push-params
Laajentaminen
Kuten voitte nähdä, onEvent kuunnella htmx:configRequest tapahtuma.
Sitten me:
- Otetaan elementti, joka käynnisti tapahtuman
- Ottakaa
preserve-params-exclude, jos se on olemassa) ja jakaa sen avainkokonaisuudeksi poistaakseen (, joten emme lisää niitä pyyntöön - Ottakaa nykyiset URL-parameterit ikkunan sijaintipaikasta
- Ottakaa uudet parametrit pyynnön URL:stä
- Läpäisy nykyisten parametrien läpi ja tarkistaa, eivätkö ne ole poissuljettu luettelossa eivätkä jo uudet parametrit
- Jos ne eivät ole,, lisäämme ne uusiin parametreihin
- Lopuksi, asetamme uudet parametrit pyynnön URL:hen ja palautamme totuuden jatkaaksemme pyyntöä.
export default {
onEvent: function (name, evt) {
if (name !== 'htmx:configRequest') return;
const el = evt.detail.elt;
const excludeStr = el.getAttribute('preserve-params-exclude') || '';
const exclude = excludeStr.split(',').map(s => s.trim());
const currentParams = new URLSearchParams(window.location.search);
const newParams = new URLSearchParams(evt.detail.path.split('?')[1] || '');
currentParams.forEach((value, key) => {
if (!exclude.includes(key) && !newParams.has(key)) {
newParams.set(key, value);
}
});
evt.detail.path = evt.detail.path.split('?')[0] + '?' + newParams.toString();
return true;
}
};
Käytän tässä olennaista HTMX.Net its tag helpers. hx-controller ja hx-action ovat merkintähelporeita, jotka tuottavat teille oikeat HTMX-ominaisuudet. sekä hx-route-<x> on todella hyödyllistä, koska se antaa mahdollisuuden käyttää C-koodia todellisten arvojen luomiseksi ominaisuuksille sen sijaan, että niitä olisi kodifioitava HTML:ssänne.
Käyttämällä sitä
Koska se on laajennus, sitä on todella helppo käyttää
Ensinnäkin meidän on lisättävä HTMX-configurationimme laajennus.
import preserveParams from './preserveParams.js';
htmx.defineExtension('preserve-params', preserveParams);
PANEE MERKILLE: Teidän on huomautettava, että HTMX:n tavanomaiset laajennusmenetelmät käyttävät 'autoloadM SK3 menetelmää ladatakseen laadinnon.
// Autoloading the extension and registering it
(function() {
htmx.defineExtension('debug', {
}
Tämä on hyvä tapa tehdä se, jos olette käyttämässä HTMX:tä muussa kuin - -muunnelmaympäristössä. import julistus ladata laajennus ja sitten nimenomaisesti rekisteröidä se vastauksena htmx instance. Tämä mahdollistaa sen, että hyödynnätte puun rakennetta -shakingia ja laaditte vain tarvitsemanne laajennusten
Sitten elementtin voin lisätä hx-ext ominaisuuksia, joiden arvo on preserve-params ja preserve-params-exclude periaate, johon sisältyy selitetty luettelo parametreista, joita pyynnöstä on poistettava.
<a class="btn-outline-icon"
hx-controller="MyController"
hx-action="MyAction"
hx-route-myparam="@MyParam"
hx-push-url="true"
hx-ext="preserve-params"
preserve-params-exclude="page,sort"
hx-target="#page-content"
hx-swap="innerHTML show:top"
hx-indicator>
<i class="bx bx-search"></i>
</a>
Tässä tapauksessa event.detail.path uusi myparam arvo asettaa sen siihen' korvaa tämän uuden arvomme, mutta säilyttää kaikki muut M SK1 lukuun ottamatta page ja sort). Voimme siis siirtää kaikki URL-osoitteessa määritellyt filtrit edelleen palveluun ilman, että meidän on huolehdittava niiden katoamisesta, kun teemme uuden pyynnön.
ASP.NET Core
HTMX:n eräs hieno asia on se, että suuri osa sen vuorovaikutuksesta serveriin tapahtuu HTTP-otsikkojen välityksellä. Nämä otsikot antavat serverille rikkaan kontekstin siitä, mikä teki pyynnön lähtökohdaksi.
Jälleen kerran tämän keskeinen osatekijä on HTMX.Net. Monista sen tarjoamista tuotteista monet ovat huolellisia Request HTMX-pyyntöjen havaitsemiseen tarkoitettuja lisäyksiä. Tämä on hyödyllinen, jotta voidaan määritellä, tekikö HT MX pyynnön vai ei, ja käsitellä sitä vastaavasti
Sillä on myös oma mekanismi,
Response.Htmx(h => {
h.WithTrigger("yes")
.WithTrigger("cool", timing: HtmxTriggerTiming.AfterSettle)
.WithTrigger("neat", new { valueForFrontEnd= 42, status= "Done!" }, timing: HtmxTriggerTiming.AfterSwap);
});
Push Urls jne...etc... Khalid teki loistavan työn laatiessaan joukon lisäyksiä, jotka helpottavat HTMXin käyttöä ASP:ssa
HTMX:n ja ASP:n kanssa työskennellessäni se on keskeinen väline. Katsokaa se!
Yleiset HTMX-pyynnön otsikot
Tässä on HTMX:n lähettämien hyödyllisimpien otsikoiden jakautuminen jokaiseen pyyntöön.
| Luettelo | |
|---|---|
| HX | |
| HXM SK1Target | DOM:n kohdeelementin ID, johon vastaus korvataan |
| HX | |
| HX | |
| HX | |
| HX | |
| HX -Historia-RestoreM SK3Täkymys SSK4 Lähetetään totuudenmukaisesti, jos pyyntö on osa historian palauttamista navigoinnin jälkeen. |
Pyydän lisäyksiä
Käytän näitä melko laajasti ASP:ssani Request.IsHtmx() , Request.IsHtmxBoosted() ja Request.IsHtmxNonBoosted() voitte helposti havaita HTMX-pyynnöt ja vastata niihin..
Esimerkiksi, Minulla on todella yksinkertainen lisäys pyyntöön, joka antaa minulle mahdollisuuden havaita, kohdennetaanko pyyntö maininiin. #page-content div. Jos se on, niin tiedän, että minun pitäisi lähettää takaisin osittainen
PANEE MERKILLE: Monet eivät realize you can specify a 'full pageM SK3 as a partial , it then just skips the layout
if (Request.PageContentTarget())
{
Response.PushUrl(Request);
return PartialView("List", vm);
}
return View("List", vm);
public static class RequestExtensions
{
public static bool PageContentTarget(this HttpRequest request)
{
bool isPageContentTarget = request.Headers.TryGetValue("hx-target", out var pageContentHeader)
&& pageContentHeader == "page-content";
return isPageContentTarget;
}
}
Vastauksen laajentaminen
Pyyntöjen laajennusten lisäksi, voitte myös luoda vastauksen laajennettuja toimenpiteitä tapahtumien lähettämiseksi takaisin klientilleM SK1 Tämä on hyödyllistä Client-puolisten tapahtumista aktivoimiseksi.
SweetAlert -esimerkki
Esimerkiksi SweetAlert2 integroinnissani Saanen lopettaa vuoropuhelun käyttämällä lähtölaukauksen, joka on asetettu palvelijalta.
document.body.addEventListener('sweetalert:close', closeSweetAlertLoader);
Tämä aktivoidaan palvelimelta HTMX:n aktivointitapahtumana.
public static void CloseSweetAlert(this HttpResponse response)
{
response.Headers.Append("HX-Trigger" , JsonSerializer.Serialize(new
{
sweetalert = "close"
}));
}
Tämä käynnistää sweetalert:close tilanteesta riippuvainen tapahtuma,, joka mahdollistaa vuoropuhelun sulkemisen HX-Trigger header. Tämä on hyödyllinen tietojen välittämiseksi palvelimelta Clientiin muuttamatta HTML- tai JavaScript-koodia
Kuten näette' on täysin helppo kuunnella näitä tapahtumia vain lisäämällä tapahtumien kuuntelijan kehoonM SK1 Käytän JSONia pääasiassa siksi, että se sekoittaa aina asianmukaisesti
ShowToast
Olen kirjoittanut aiemmin savutusmenetelmästäni täällä, mutta se ' kannattaa mainita myös täälläM SK2 Voidakseni hyvin yksinkertaisesti aktivoida serverin toast-ilmoituksen Client-puolelle. Asetsin aktivaattorin tähän vastauksen laajennuseen
public static void ShowToast(this HttpResponse response, string message, bool success = true)
{
response.Headers.Append("HX-Trigger", JsonSerializer.Serialize(new
{
showToast = new
{
toast = message,
issuccess =success
}
}));
}
Siirryn sitten tapahtuman asiakkaiden puoleen ja kutsun showToast Funktio.
import { showToast, showHTMXToast } from './toast';
window.showHTMXToast = showHTMXToast;
document.body.addEventListener("showToast", showHTMXToast);
Tämä kutsuu sitten minuun showToast function and well, osoittaa toastM SK1 jälleen nähdä enemmän siitä artiklassa .
export function showHTMXToast(event) {
const xhr = event?.detail?.xhr;
let type = 'success';
let message = xhr?.responseText || 'Done!';
try {
const data = xhr ? JSON.parse(xhr.responseText) : event.detail;
if (data.toast) message = data.toast;
if ('issuccess' in data) {
type = data.issuccess === false ? 'error' : 'success';
} else if (xhr?.status >= 400) {
type = 'error';
} else if (xhr?.status >= 300) {
type = 'warning';
}
} catch {
if (xhr?.status >= 400) type = 'error';
else if (xhr?.status >= 300) type = 'warning';
}
showToast(message, 3000, type);
}
Päätelmissä
No niin, että's se,hirlwind Tour of HTMX and ASP .NET CoreM SK3 Toivon, että olette löytäneet sen hyödylliseksi ja informativeksiMSC4 Jos teillä on kysymyksiä tai huomautuksia, voitte ystävällisesti kommentoida sitä jäljempänä.
Related Articles on This Blog
Yhteinen artikla
Tämä artikla on osa HTMX:n kahta osasarjaa ASP:n kanssa
- HTMX ASP.NETin ydinosapuolten kanssa - keskittyy ASP:iinM SK1NETin ydinintegraatioon , osittaisiin näkemyksiin M SK3 HTMX.NETMSC5 ja sivuuttamiseen
- Tämä artikkeli - HTMX-tapahtumiin syvällinen virtaaminen , elinkaari
Lisätietoja HTMX-artikkeleista
- HTMX:n kanssa vuoropuhelujen lisääminen - HTMX:n kanssa toteutettava sivuutus
- ASP.NET Core Caching HTMXin avulla - HTMX-pyyntöjen tallentamisstrategiat
- Auto-refresh with Alpine and HTMX - Alpine'n ja HTMX:n yhdistäminen reaktiivisiin komponentteihin
- Siten lisääminen SPA-kuten HTMX-järjestelmässä - SPA-navigointi ilman JavaScript-puitteita
- SweetAlertin käyttö HX-indikaattorien osalta - kauniit lastausindikaattorit HTMX:llä
- Toast- ja Swapping HTMX:n avulla -Serveri-pyynnellyt toast-ilmoitus
Lisä lukeminen
Virallinen HTMX-asiakirja:
- HTMX-asiakirja - Virallinen HTMX-asiakirja
- HTMX-tapahtumat - HTMX-tapahtumien täydellinen luettelo
- HTMX-laajennukset - viralliset HTMX-laajennukset
- HTMX-esimerkit - HTMX-muodon käytännön esimerkkejä
- HTMX-kertomukset - HTMX-filosofiaa koskevat ajatuksia herättävät artikkelit
Luettelo kirjastoista & välineet:
- HTMX.NET GitHub - HTMX-lähdekoodi
- HTMX.NET NuGet - HTMX.NET NuGetissä
- Khalid Abuhakmeh MSK:n verkkosivusto - HTMX:n luoja
- Alpine.js-asiakirja - Virallinen alppimaajoukkue
Yhteisön resurssit:
- HTMX-erimistö - Aktiivinen yhteisötuki
- Hypermedia Systems -kirja - Vapaa verkkokirja hypermedia-sovellusten rakentamisesta