In ambito informatico, soprattutto nella programmazione web, molto spesso sentiamo parlare di file di template e binding dei dati.
Ma cosa c'entrano con questa 👆🏼 foto? 😅
E cosa sono veramente?
Beh, la risposta alla prima domanda è che essi sono un po' come la ciliegina sulla torta, come quella foglia di basilico sopra quel magnifico piatto di agnolotti (si, sono agnolotti). 😋
Hanno la funzione di semplificare e completare il vostro lavoro.
Per la seconda domanda invece, cerchiamo di fare un po' di chiarezza attorno a questi due concetti.
I motori di template JavaScript
Con la crescita di JavaScript, in ottica di effettuare la scelta di un framework tra gli innumerevoli ormai disponibili, non si può non tener conto del tipo di motore di template che si andrà ad utilizzare.
Meglio conosciuti come templating engines, essi sono uno strumento per separare la struttura HTML dal contesto contenuto al suo interno. Il template è generalmente un file scritto in un linguaggio di markup, non puro HTML perché esso non fornisce questo tipo di supporto, ma in un altro linguaggio, il quale, una volta compilato dal motore di template associato, diverrà HTML interpretabile dal browser.
I motori di template generalmente introducono qualche nuova sintassi ma sono molto semplici da utilizzare.
Il concetto alla base è quello di avere delle variabili (o segnaposto) all’interno del linguaggio HTML, le quali verranno valorizzate non appena il dato a loro associato sarà disponibile.
Una pratica frequente consiste nell'utilizzare doppie parentesi graffe per porre al loro interno tali variabili, ad esempio {{variabile}}
, per avere un collegamento (binding in inglese) tra il template in cui è usata ed il valore restituito da una sorgente di dati.
La sorgente potrà poi essere un semplice oggetto JSON, un controller, una view o altro.
Il concetto importante da sottolineare in questo caso è che mentre il testo (il nome della variabile) usato nel template rimane invariato, i dati possono essere diversi ad ogni chiamata.
Per rendere meglio l’idea ecco un esempio partendo dal template:
<h1>{{titolo}}</h1>
<p>{{testo}}</p>
Come potrete notare, abbiamo scritto una specie di HTML con una sintassi leggermente diversa, esso rappresenta il nostro file di template.
Se sostituissimo {{titolo}}
con, ad esempio, "JavaScript" e {{testo}}
con "Linguaggio interpretato", il risultato dopo la compilazione del template, sarebbe il seguente file HTML:
<h1>JavaScript</h1>
<p>Linguaggio interpretato</p>
Ora, se avessimo necessità di avere lo stesso layout, potremmo riutilizzare lo stesso template cambiando solamente la valorizzazione delle variabili titolo e testo, per esempio rispettivamente con "Java" e "Linguaggio compilato".
Il risultato sarebbe un altro file HTML sì fatto:
<h1>Java</h1>
<p>Linguaggio compilato</p>
Infine, se volessimo modificare il layout sostituendo il tag <p>
con un <div>
, basterà modificare il solo file di template.
Lo stretto legame tra template e sorgente dati che stiamo illustrando prende anche il nome di binding di dati dichiarativo o declarative data binding.
Ecco un altro esempio in cui il valore della variabile in binding, influenza l’attributo di un elemento HTML:
<input type="checkbox" checked="{{contatto.haFoto}}"/>
Il template rappresenta una classica checkbox in HTML la quale è collegata ad un oggetto, in questo caso contatto, la cui proprietà haFoto possiederà un valore true nel caso il contatto abbia una foto associata, false altrimenti.
Di conseguenza, essendo il valore di questa variabile collegato direttamente alla proprietà checked della checkbox, essa sarà selezionata se il contatto avrà una foto associata, non selezionata se esso non l’avrà.
Semplice no?
Utilizzare questo tipo di strumento non è obbligatorio e nemmeno necessario se si vuole costruire un’applicazione client side, ma piuttosto che usare una libreria come jQuery per aggiornare l’HTML quando i valori cambiano, questo tipo di soluzione garantisce una pulizia del codice non indifferente, senza doversi preoccupare di come aggiornare la visualizzazione dei dati per mostrare i nuovi valori.
I motori di template più famosi sono: Mustache, Underscore, Handlebars, Jade; non ci addentreremo nella loro descrizione perchè a grandi linee tutti fanno ciò che abbiamo illustrato.
Tipi di data binding
Dopo aver visto cosa sono i motori di template, sembra doveroso avere una breve panoramica di quali siano i principali tipi di data binding esistenti. Come abbiamo notato nel paragrafo precedente, è molto importante la correlazione che vi è tra il nostro template, il codice javascript che lo governa ed i nostri dati. Il binding di dati (o associazione dati) è il processo di sincronizzazione che intercorre tra i componenti di visualizzazione della UI ed i dati stessi.
Supponiamo di avere sempre la nostra solita checkbox nel nostro template, essa naturalmente è cliccabile da un utente e sarà collegata ad una variabile all’interno del nostro codice. Cosa vi aspettereste una volta che lo user avrà eseguito il click su tale componente? Che la variabile a cui è collegata cambi anch’essa, riflettendo sempre il valore visualizzato? O che la variabile mantenga il valore originario finché un altro evento renderà persistente la scelta effettuata dall’utente? Quale comportamento è “meglio”?
Partendo da quest’ultima domanda, come quasi sempre avviene per questa tipologia di quesiti la risposta è “dipende”. Dipende da cosa vogliamo ottenere come risultato e da che cosa necessitiamo.
☝🏼 One way binding (associazione dati unidirezionale)
Ampliamo il nostro mini esempio e supponiamo che tale checkbox sia inserita in un form dove per confermare i dati immessi si debba cliccare il tasto salva. In tale situazione, molto probabilmente, non vogliamo che ad ogni click, il valore della variabile a cui la checkbox è associata cambi, vorremmo semplicemente far fare all’utente le sue scelte, e rendere i dati persistenti solo quando esso clicca su salva.
Questo è il tipico caso di one way binding (detto anche associazione di dati unidirezionale). Nel one way binding, i dati associati al componente nel template non cambiano se interagiamo e cambiamo il valore di tale componente:
✌🏼 Two way binding (associazione dati bidirezionale)
Supponiamo invece di avere un modulo in cui non è presente alcun tasto e tutte la scelte effettuate dall’utilizzatore vengono salvate immediatamente.
Questo, viceversa, è il tipico caso di two way binding (detto anche associazione di dati bidirezionale). Nel two way binding, i dati associati alla UI cambiano a seconda dei valori dati in input tramite la UI e viceversa, cambiando i dati, anche la UI viene aggiornata di conseguenza: