Il controllo del flusso in Alpine avviene attraverso le direttive x-if
e x-for
, utilizzando l'elemento <template>
.
<template>
è un elemento HTML5 che permette di definire frammenti di markup che non vengono renderizzati immediatamente nel DOM. Può essere considerato un contenitore invisibile di frammenti di markup utilizzabili in seguito via JavaScript.
In Alpine l'elemento <template>
è utilizzato insieme alle direttive x-if
e x-for
per gestire il rendering condizionale o iterativo dei blocchi di codice contenuti.
Il rendering condizionale: la direttiva x-if
La direttiva x-if
genera o elimina un elemento in base ad una condizione. Se l'espressione passata a x-if
è true
, l'elemento cui è assegnata la direttiva appare nel documento, se è false
, viene rimosso dal DOM.
Se la funzione di x-if
può sembrare simile a x-show
, va sottolineato che la direttiva x-show
rende un elemento visibile o invisibile senza rimuoverlo dal DOM.
x-if
non va assegnato direttamente all'elemento da controllare ma a un <template>
che racchiude l'elemento da rendere o rimuovere. In questo modo Alpine può tenere una traccia dell'elemento nel caso in cui questo venga rimosso. Ecco un esempio:
<div x-data="{ show: true }">
<template x-if="show">
<p>Questo paragrafo è visibile solo se show è true.</p>
</template>
</div>
La documentazione avverte che, a differenza di x-show
, x-if
non supporta le transizioni con x-transition
. Altro avvertimento riguarda il contenuto di <template>
, che può contenere un solo elemento root.
I cicli iterativi: la direttiva x-for
La direttiva x-for
permette di iterare tra gli elementi di un array o di un oggetto esattamente come un ciclo for
in JavaScript. Come avviene con x-if
, anche con x-for
è necessario racchiudere il codice HTML da generare ad ogni ciclo all'interno di un elemento <template>
.
Per ogni elemento della collezione (array o oggetto), Alpine clona il contenuto dell'elemento <template>
e lo inserisce nel DOM. Vediamo un esempio:
<div x-data="{ users: [
{ name: 'Mario', age: 25 },
{ name: 'Luisa', age: 30 },
{ name: 'Giulia', age: 28 }
] }">
<table>
<thead>
<tr>
<th>Nome</th>
<th>Età</th>
<th>Azione</th>
</tr>
</thead>
<tbody>
<template x-for="user in users" :key="user.name">
<tr>
<td x-text="user.name"></td>
<td x-text="user.age"></td>
<td>
<button @click="user.age++">Incrementa età</button>
</td>
</tr>
</template>
</tbody>
</table>
</div>
- La direttiva
x-for="user in users"
itera sull'arrayusers
e genera una riga di tabella per ogni elemento. :key="user.name"
permette ad Alpine di tenere traccia del blocco HTML generato ad ogni ciclo.- Il pulsante permette di incrementare l'età dell'elemento corrente al clic dell'utente:
@click="user.age++"
.
L'immagine che segue mostra il risultato a video.

L'output della direttiva x-for
di Alpine
Il binding in Alpine: x-bind
e x-model
Il data binding è una tecnica che permette di collegare automaticamente i dati di un'applicazione con gli elementi dell'interfaccia utente. Ciò in modo che le modifiche nei dati si riflettano direttamente nell'interfaccia (binding unidirezionale) o viceversa (binding bidirezionale).
In Alpine, il data binding unidirezionale avviene tramite la direttiva x-bind
. Essa permette di collegare dinamicamente gli attributi di un elemento HTML a espressioni JavaScript definite nel contesto di Alpine. Lo scopo di x-bind
è aggiornare attributi o proprietà di un elemento in modo reattivo al cambiamento dei dati.
La sintassi prevede l'utilizzo di x-bind
seguito da due punti e l'attributo target. Ad esempio, x-bind:class
. È possibile anche utilizzare solo i due punti :
nella forma abbreviata, ad esempio :class
. Ecco un semplice esempio:
<style>
.active {
background-color: lightgreen;
}
.inactive {
background-color: lightcoral;
}
</style>
<body>
<div x-data="{ isActive: false }">
<div x-bind:class="isActive ? 'active' : 'inactive'">
Elemento dinamico.
</div>
<button @click="isActive = !isActive">
Cambia stato
</button>
</div>
</body>
Al clic sul pulsante, il valore di isActive
passa da true
a false
e viceversa e x-bind
assegna dinamicamente il nuovo valore all'attributo class
della div
.
Le due immagini che seguono mostrano i cambiamenti nel codice e a video.

Esempio di x-bind:class

Esempio di x-bind:class
Vediamo un esempio più complesso
<style>
button {
padding: 10px;
font-size: 16px;
}
.disabled-text {
color: gray;
}
</style>
<div x-data="{ isDisabled: true }">
<button x-bind:disabled="isDisabled" @click="alert('Pulsante cliccato!')">
Cliccami
</button>
<p x-bind:class="{ 'disabled-text': isDisabled }">
Stato del pulsante: <span x-text="isDisabled ? 'Disabilitato' : 'Abilitato'"></span>
</p>
<button @click="isDisabled = !isDisabled">
Cambia stato
</button>
</div>
Al clic sul pulsante Cambia stato
viene assegnato o rimosso dinamicamente l'attributo disabled
al pulsante Cliccami
e modificato il testo del paragrafo. Le due immagini che seguono mostrano come cambia il codice HTML e il risultato a video.

Esempio di x-bind:disabled

Esempio di x-bind:disabled
Oltre al binding unidirezionale con x-bind
, Alpine dispone della direttiva x-model
che permette di sincronizzare i dati e l'interfaccia utente sono sincronizzati in entrambe le direzioni. Modifiche nei dati si riflettono nell’interfaccia e modifiche nell’interfaccia da parte dell'utente aggiornano automaticamente i dati.
x-model
viene utilizzato con i seguenti elementi di moduli:
<input type="text">
<textarea>
<input type="checkbox">
<input type="radio">
<select>
<input type="range">
Vediamo un esempio semplice:
<div x-data="{ messaggio: 'Scrivi qui il testo' }">
<input type="text" x-model="messaggio" placeholder="Inserisci testo">
<p>Il tuo testo: <span x-text="messaggio"></span></p>
</div>
In questo esempio, x-model
collega il campo di testo alla variabile messaggio
. Qualsiasi modifica nel campo aggiorna messaggio
, e viceversa.
Ecco un esempio più complesso:
<style>
.color-box {
width: 200px;
height: 200px;
margin-top: 20px;
border: 1px solid #ccc;
}
.range-container {
margin: 10px 0;
font-family: Arial, sans-serif;
}
</style>
<div x-data="{ red: 128, green: 128, blue: 128 }">
<div class="range-container">
<label>Rosso: <span x-text="red"></span></label><br>
<input type="range" min="0" max="255" x-model.number="red">
</div>
<div class="range-container">
<label>Verde: <span x-text="green"></span></label><br>
<input type="range" min="0" max="255" x-model.number="green">
</div>
<div class="range-container">
<label>Blu: <span x-text="blue"></span></label><br>
<input type="range" min="0" max="255" x-model.number="blue">
</div>
<div
class="color-box"
x-bind:style="`background-color: rgb(${red}, ${green}, ${blue});`"
></div>
</div>
x-data="{ red: 128, green: 128, blue: 128 }"
: inizializza lo stato con tre variabili, ognuna con un valore iniziale di 128;<input type="range" x-model.number="...">
: seguono tre slider collegati alle tre variabilired
,green
eblue
. Il modificatorenumber
forza Alpine a considerare il valore come numerico;<div x-bind:style="background-color: rgb(${red}, ${green}, ${blue});">
: imposta dinamicamente il colore di sfondo delladiv
con la sintassi RGB.
L'immagine che segue mostra il risultato a video.

Binding bidirezionale con x-model
in Alpine