En Auto-Update Partiell Updater med Alpine.js och HTMX (Svenska (Swedish))

En Auto-Update Partiell Updater med Alpine.js och HTMX

Wednesday, 23 April 2025

//

8 minute read

Inleiding

Så i vad som blir en serie- -, i ett arbetsprojekt ville jag lägga till möjligheten att göra en del- -automatiskt- -update på en given tidsskala.

Här är hur jag gjorde det med Alpine.

Benötningar

Så jag ville att detta skulle vara

  1. återanvändbar; så att det ska vara enkelt och självständigt
  2. Det borde respektera de existerande Url-parameterna
  3. Den borde vara upptäckbar på serversidan (i ASP.NET Core i detta fallet )
  4. Om den är aktiverad borde den aktiveras för den slutpunkten bara och detta bör komma ihåg mellan begäran
  5. Den borde göra uppgraderingen omedelbart när den är aktiverad ( så att användaren vet hur den ser ut
  6. Den borde kunna stängas av av av användaren
  7. Det borde vara enkelt att inkludera på en sida.

Med detta i åtanke bestämde jag mig för att bygga ett litet JS-modul med Alpine.js och HTMX.

NOTA

Du kan göra automatiska uppdaterade system utan att behöva ' på och av' och ' komma ihågM SK3 egenskaper på ett ganska enkelt sätt bara med HTMX Till exempel; med HTMX Sneller du kan verkligen göra en massa saker


<div id="campaignemail-request-list" hx-get="@Url.Action("List", "CampaignEmailRequest")" hx-trigger="every 30s" hx-swap="innerHTML">
    <partial name="_List" model="@Model"/>
</div>

Tack till @KhalidAbuhakmeh för att peka ut detta.

Denna kod använder faktiskt hx-trigger att installera den automatiska versionen. Det är därför HTMX med Alpine.js är en så kraftfull kombination ; HT MX hanterar alla serverinteraktioner och AJAX-inlärningar , medan Alpine~.js hanterar klientseitiga tillstånd och interaktioner M SK5 Kan du också göra det här i Vanilla JS?

Koden

Koden för detta är verkligen ganska kompakt.

Modulet

Modulet är ett enkelt JS-modul som använder Alpine.js för att sköta tillståndet på den automatiserade versionen

Den accepterar fraserna :

  • endpointId - ID av elementet som ska uppdateras
  • actionUrl - url som ska kallas för att uppdatera elementet
  • initialInterval - det initiala intervallet som skall användas för den automatiserade versionen

Vi kan också se att den använder ett par nycklar; som används för plats lagring för att komma ihåg tillståndet på den automatiserade versionen Ni kan se att jag använder actionurl som en del av nyckeln till att göra detta slutpunkt specifikt.

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() Metod

Den här metoden aktiverar eller avsperar automatisk rösting på ett HTML element med hjälp av HTMX.

Vanor

  • Väljer ett element genom dess endpointId.
  • Bygger upp begäran URL (fullUrl) genom att kombinera den geda actionUrl med den nuvarande sidan's söktråd.
  • Ser om folkröstning tidigare aktiverats genom att läsa från localStorage (bra eftersom det kommer ihågs mellan webblader sessioner).

När this.autoUpdate är true (, i, ., e, M SK2, folkröstning är aktiverad

  • Inser HTMX-attribute på elementet:
    • hx-trigger att rösta på varje interval sekunder
    • hx-swap="innerHTML" för att ersätta elementet’s innehåll
    • hx-get för att peka på röstsedelns URL
    • hx-headers att lägga till en anpassad "AutoPoll": "auto" header
  • sparar den aktiverade tillståndet till localStorage
  • Rörningar htmx.process(el) att låta HTMX känna igen de nya egenskaperna
  • Om den tidigare var avstängd, triggar den omedelbart en HTMX-fråga via htmx.ajax() ( inte förlitar sig på HTMX-inspelning

När this.autoUpdate är false (, i, ., e, M SK2, rösting är avstängd

  • Removerar de tidigare HTMX-attributena
  • Klarar sparade inställningarna från localStorage
  • Rörningar htmx.process(el) att uppdatera HTMX-beteende igen

Automatisk Poll när den först aktiveras

Vi har också en gren här för att utföra automatiseringen.

const wasPreviouslyEnabled = localStorage.getItem(enabledKey) === 'true';
      if (!wasPreviouslyEnabled) {
                    htmx.ajax('GET', fullUrl, {
                        target: el,
                        swap: 'innerHTML',
                        headers: {AutoPoll: 'auto'}
                    });
                }

Detta utför en HTMX- begäran till fullUrl och uppdaterar målelementet med svaret. Det är användbart för att visa till användaren hur det kommer att se ut i automatiseringen när de aktiverar den

Påskriftar

Ni kommer att lägga märke till att vi även skickar en HTMX-Header med begäran. Detta är viktigt eftersom det tillåter oss att upptäcka begäran serversidan.

   el.setAttribute('hx-headers', JSON.stringify({ AutoPoll: 'auto' }));
headers: {AutoPoll: 'auto'}

På min server sida upptäcker jag att den här headern ställs med

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

Ni ' ser att jag bara letar efter rubriken med Request.Headers.TryGetValue("AutoPoll", out _) och om det är där, så vet jag att det är en automatiserad fråga.

Jag tar sedan den nuvarande yimen (it 's för en fransk kundM SK2 så jag konverterar till Paristid) och visar en toast med tiden

ShowToast

Den ShowToast metod är en enkel förlängningsmetod som sätter en aktivator för att säga till HTMX att visa ett toast meddelande.

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

    }

Detta upptäcks sedan av min HTMX toastkomponent som visar meddelandet.

document.body.addEventListener("showToast", (event) => {
    const { toast, issuccess } = event.detail || {};
    const type = issuccess === false ? 'error' : 'success';
    showToast(toast || 'Done!', 3000, type);
});

Det här låter in i min brödkomponent I skrev om det här .

Att häcka upp det

Det är ganska enkelt att koppla upp den här modulen, ,, i din huvudversion. ., js, \ index, M SK4, JS vad som helst, bara importera den och ansluta den till Windows

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

Sedan kallar vi init-metoden i ASP

ASP.NET Razor kod

För att göra detta så litet och återanvändbart som möjligt är koden för Razor ganska enkel.

Här kan ni se att jag specifikerar Alpine.js data-attributen för att sätta upp den automata

  • x-data: Det här är där vi sätter upp Alpine dataobjektet
  • x-init: Det här är där vi kallar init-metoden på den automata
  • x- påM SK1 förändring : Det här är där vi kallar för toggleAutoUpdate-metoden på den automata
  • data- slutpunkt-idM SK2 Detta är IDet för elementet som ska uppdateras
  • data-actionM SK1url: Detta är url som ska kallas för att uppdatera elementet
  • data-interval

Du' ser att vi har ställt målet att använda för begäran till campaignemail-request-list element. Detta är elementet som kommer att bli uppdaterat med den nya innehållet Det "'" då inkluderades SOMMES på sidan

Nu när en checkbox är kontrollerad kommer den att automatiskt uppdatera listan varje 30 sekund

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

I slutsats

Och det är detta: HTMX och Alpine: .js används för att skapa en enkel automatiserad komponent som vi enkelt kan använda från ASP.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.