NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Wednesday, 23 April 2025
//Less than a minute
In dem, was zu einer Serie wird, wollte ich in einem Arbeitsprojekt die Fähigkeit für einen Teil hinzufügen, Auto-Update auf einer bestimmten Zeitskala.
So habe ich es mit Alpine.js und HTMX gemacht.
Also wollte ich, dass das so ist
In diesem Sinne wollte ich ein kleines JS-Modul mit Alpine.js und HTMX bauen.
Sie können Auto-Updates der 'on and off' und'remember' Funktionen ziemlich einfach mit HTMX allein. Zum Beispiel; mit HTMX-Trigger Du kannst wirklich viel tun.
<div id="campaignemail-request-list" hx-get="@Url.Action("List", "CampaignEmailRequest")" hx-trigger="every 30s" hx-swap="innerHTML">
<partial name="_List" model="@Model"/>
</div>
Dank @KhalidAbuhakmeh dafür, dass ich darauf hingewiesen habe.
Dieser Code verwendet in der Tat hx-trigger
um das Auto-Update einzurichten. Verwenden Sie Alpine.js, um die HTMX-Attribute zu konfigurieren.
Was dies wirklich ergänzt, ist die User-Interaktion Client-Seite; das ist, was Alpine.js ist großartig.
Der Code dafür ist wirklich ziemlich kompakt, er ist in zwei Hauptteile aufgeteilt: ein JS-Modul, die Event-Handler und das HTML.
Das Modul ist ein einfaches JS-Modul, das mit Alpine.js den Zustand des Auto-Updates verwaltet. Es verwendet lokalen Speicher, um den Zustand des Auto-Update zwischen Anfragen zu speichern.
Es akzeptiert die Parameter:
endpointId
- die ID des zu aktualisierenden ElementsactionUrl
- die URL, die aufgerufen werden soll, um das Element zu aktualisiereninitialInterval
- das für das Auto-Update zu verwendende Anfangsintervall (Standard ist 30 Sekunden)Wir können auch sehen, dass es ein paar Schlüssel verwendet; diese werden für den lokalen Speicher verwendet, um den Zustand des Auto-Updates zu speichern.
Sie können sehen, dass ich die actionurl
als Teil des Schlüssels, um diesen Endpunkt spezifisch zu machen.
export function autoUpdateController(endpointId, actionUrl, initialInterval = 30) {
const keyPrefix = `autoUpdate:${actionUrl}`;
const enabledKey = `${keyPrefix}:enabled`;
return {
autoUpdate: false,
interval: initialInterval,
toggleAutoUpdate() {
const el = document.getElementById(endpointId);
if (!el) return;
const url = new URL(window.location.href);
const query = url.searchParams.toString();
const fullUrl = query ? `${actionUrl}?${query}` : actionUrl;
const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
if (this.autoUpdate) {
el.setAttribute('hx-trigger', `every ${this.interval}s`);
el.setAttribute('hx-swap', 'innerHTML');
el.setAttribute('hx-get', fullUrl);
el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
localStorage.setItem(enabledKey, 'true');
htmx.process(el); // rebind with updated attributes
if (!wasPreviouslyEnabled) {
htmx.ajax('GET', fullUrl, {
target: el,
swap: 'innerHTML',
headers: {AutoPoll: 'auto'}
});
}
} else {
el.removeAttribute('hx-trigger');
el.removeAttribute('hx-get');
el.removeAttribute('hx-swap');
el.removeAttribute('hx-headers');
localStorage.removeItem(enabledKey);
htmx.process(el);
}
},
init() {
this.autoUpdate = localStorage.getItem(enabledKey) === 'true';
this.toggleAutoUpdate();
}
};
}
toggleAutoUpdate()
VerfahrenDiese Methode ermöglicht oder deaktiviert die automatische Abfrage eines Ziel-HTML-Elements mit HTMX.
endpointId
.fullUrl
) durch Kombination der angegebenen actionUrl
mit dem Abfrage-String der aktuellen Seite.localStorage
(gut, wie es zwischen den Browser-Sitzungen erinnert wird).this.autoUpdate
wird true
(d.h. Umfragen sind aktiviert):hx-trigger
zu jeder Umfrage interval
Sekundenhx-swap="innerHTML"
den Inhalt des Elements zu ersetzenhx-get
um auf die Umfrage-URL zu verweisenhx-headers
um einen Custom hinzuzufügen "AutoPoll": "auto"
KopfzeilelocalStorage
htmx.process(el)
HTMX die neuen Attribute erkennen lassenhtmx.ajax()
(nicht auf HTMX-Ereignisverkabelung angewiesen)this.autoUpdate
wird false
(d.h. Umfragen sind deaktiviert):localStorage
htmx.process(el)
wieder zum Aktualisieren des HTMX-VerhaltensWir haben auch einen Zweig hier, um das Auto-Poll durchzuführen, wenn zuerst aktiviert.
const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
if (!wasPreviouslyEnabled) {
htmx.ajax('GET', fullUrl, {
target: el,
swap: 'innerHTML',
headers: {AutoPoll: 'auto'}
});
}
Dies führt eine HTMX-Anfrage an die fullUrl
und aktualisiert das Zielelement mit der Antwort. Dies ist nützlich, um dem Benutzer zu zeigen, wie das Auto-Update aussehen wird, wenn sie es aktivieren.
Sie werden feststellen, dass wir auch einen HTMX-Header mit der Anfrage senden. Dies ist wichtig, da es uns erlaubt, die Request-Server-Seite zu erkennen.
el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
headers: {AutoPoll: 'auto'}
Auf meiner Serverseite erkenne ich dann, dass dieser Header mit
if (Request.Headers.TryGetValue("AutoPoll", out _))
{
var utcDate = DateTime.UtcNow;
var parisTz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Paris");
var parisTime = TimeZoneInfo.ConvertTimeFromUtc(utcDate, parisTz);
var timeStr = parisTime.ToString("yyyy-MM-dd HH:mm:ss");
Response.ShowToast($"Auto Update Last updated: {timeStr} (paris)",true);
return PartialView("_List", requests);
}
Du wirst sehen, ich suche einfach nach dem Header mit Request.Headers.TryGetValue("AutoPoll", out _)
Und wenn es da ist, weiß ich, dass es eine Autopoll-Anfrage ist.
Ich nehme dann das aktuelle Yime (es ist für einen französischen Kunden, also bekehre ich mich in Paris Zeit) und zeige einen Toast mit der Zeit.
Das ShowToast
Methode ist eine einfache Erweiterungsmethode, die einen Trigger setzt, um HTMX zu sagen, eine Toast-Nachricht anzuzeigen.
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
}
}));
}
Dies wird dann von meiner HTMX Toast-Komponente erkannt, die die Meldung anzeigt.
document.body.addEventListener("showToast", (event) => {
const { toast, issuccess } = event.detail || {};
const type = issuccess === false ? 'error' : 'success';
showToast(toast || 'Done!', 3000, type);
});
Dies ruft dann in meine Toast-Komponente I schrieb über hier .
Es ist ziemlich einfach, dieses Modul zu verbinden, in Ihrem main.js \ index.js was immer es gerade importieren und es an Fenster anschließen
import './auto-actions';
window.autoUpdateController = autoUpdateController; //note this isn't strictly necessary but it makes it easier to use in the HTML
//Where we actually hook it up to Alpine.js
document.addEventListener('alpine:init', () => {
Alpine.data('autoUpdate', function () {
const endpointId = this.$el.dataset.endpointId;
const actionUrl = this.$el.dataset.actionUrl;
const interval = parseInt(this.$el.dataset.interval || '30', 10); // default to 30s
return autoUpdateController(endpointId, actionUrl, interval);
});
});
Wir rufen dann die init-Methode im ASP.NET-Razor-Code auf:
Um dies so klein und wiederverwendbar wie möglich zu machen, ist der Razor-Code ziemlich einfach.
Hier sehe ich die Datenattribute Alpine.js, um das Auto-Update einzurichten.
Sie werden sehen, wir setzen das Ziel für die Anfrage zu verwenden, um die campaignemail-request-list
.............................................................................................................................................. Dies ist das Element, das mit dem neuen Inhalt aktualisiert wird.
Das ist dann enthalten SOMEWHERE in der Seite.
Wenn nun ein Kontrollkästchen aktiviert ist, wird die Liste automatisch alle 30 Sekunden aktualisiert.
<div class=" px-4 py-2 bg-base-100 border border-base-300 rounded-box"
x-data="autoUpdate()"
x-init="init"
x-on:change="toggleAutoUpdate"
data-endpoint-id="campaignemail-request-list"
data-action-url="@Url.Action("List", "CampaignEmailRequest")"
data-interval="30"
>
<label class="flex items-center gap-2">
<input type="checkbox" x-model="autoUpdate" class="toggle toggle-sm" />
<span class="label-text">
Auto update every <span x-text="$data.interval"></span>s
</span>
</label>
</div>
<!-- Voucher List -->
<div id="campaignemail-request-container">
<div
id="campaignemail-request-list">
<partial name="_List" model="@Model"/>
</div>
</div>
Und das war's, ganz einfach richtig. Mithilfe von HTMX und Alpine.js erstellen wir eine einfache Auto-Update-Komponente, die wir problemlos von ASP.NET Core nutzen können.