Nel capitolo precedente abbiamo iniziato a esplorare i tag e i controlli che abbiamo a disposizione in WinJS; gli strumenti utilizzati sono fondamentalmente gli stessi ai quali ci siamo abituati realizzando normali pagine web, mentre i controlli WinJS ci permettono di aggiungere facilmente funzionalità più evolute. Essi rappresentano sicuramente dei mattoni fondamentali, ma da soli non sono sufficienti a realizzare applicazioni "vincenti". Se abbiamo avuto modo di visionare alcune delle applicazioni presenti nello store di Windows 8, infatti, ci saremo resi conto di come esistano dei pattern specifici secondo i quali organizzare l'interfaccia tra cui, per esempio, l'aggregazione dei vari elementi in strutture a griglia o a lista, magari suddivise in gruppi. Per imparare a realizzare interfacce di questo tipo, è molto importante conoscere i controlli pensati per rappresentare sullo schermo molteplici elementi; ListView, nella fattispecie, rappresenta un'assoluta novità, introdotta appositamente per le applicazioni Windows 8, e quindi le abbiamo dedicato gran parte di questo capitolo. Una new entry è anche SemanticZoom, che ci consente di reagire a una gesture di zoom da parte dell'utente, con lo scopo di mostrare, per esempio, delle informazioni di riepilogo. Anche per ciò che concerne la navigazione o la gestione di comandi e opzioni esiste un oggetto specifico: stiamo parlando di AppBar, e ancora una volta l'astrazione dei controlli di WinJS ci mette a disposizione uno strumento di alto livello, che incapsula una serie di funzionalità e di animazioni, ed è immediatamente utilizzabile nelle nostre pagine. L'obiettivo di questo capitolo è proprio quello di imparare a sfruttare tutti questi oggetti in modo che, al termine, abbiamo in mano tutti gli strumenti necessari per realizzare applicazioni, anche complesse, con la necessaria padronanza.
Visualizzare elenchi di elementi
Il modo più elementare per mostrare elenchi di elementi in HTML 5 consiste nello sfruttare i tag ul e li, generandoli magari a partire da un array di valori, come nell'esempio 5.1.
var dataSource = ["Marco", "Cristian", "Alessio", "Stefano"];
function bindData() {
dataSource.forEach(function (o) {
var element = document.createElement("li");
element.innerHTML = o;
container.appendChild(element);
});
}
L'array dataSource che abbiamo utilizzato non è altro che una lista di stringhe, per ognuna delle quali creiamo manualmente un elemento li che accodiamo al tag container. Questa soluzione è sicuramente accettabile nel contesto che abbiamo appena analizzato, ma mostra tutti i suoi limiti quando il markup da generare è più complesso. In questi casi, fortunatamente, il controllo Template di WinJS ci semplifica molto il compito: grazie a questo controllo, possiamo specificare il markup secondo cui rappresentare ogni singolo elemento. In questo modo siamo anche in grado di legare in binding oggetti complessi. Se, per esempio, ogni elemento della lista è un oggetto con i campi name ed email, possiamo definire un template specifico come nell'esempio 5.2.
<div id="listTemplate" data-win-control="WinJS.Binding.Template">
<div>
<h5 data-win-bind="innerHTML: name"></h5>
<a data-win-bind="href: email">Invia email</a>
</div>
</div>
<div id="target"></div>
Come siamo ormai abituati a sapere, un controllo WinJS altri non è che un tag HTML dotato dell'attributo data-win-control. Nel nostro caso, listTemplate contiene una serie di ulteriori elementi, che indicano con data-win-bind come il contenuto dell'oggetto in binding dovrà popolarli. Entrando nello specifico, il nome sarà l'innerHTML di un tag h5, mentre l'indirizzo email verrà utilizzato come href per un link. L'oggetto template, fintanto che non viene collegato a una fonte dati, non produce alcun markup e resta completamente invisibile. Possiamo però sfruttarlo per riempire il div denominato target, con il codice dell'esempio 5.3.
var complexSource = [
new Person("Marco", "mailto:cradle@aspitalia.com"),
new Person("Cristian", "mailto:ricciolo@aspitalia.com"),
new Person("Alessio", "mailto:novecento@aspitalia.com"),
new Person("Stefano", "mailto:sm@aspitalia.com")
];
function bindData() {
var templateControl = listTemplate.winControl;
complexSource.forEach(function (o) {
templateControl.render(o, target);
});
}
La logica di fondo non si discosta più di tanto rispetto a quanto visto in precedenza, anche se questa volta non siamo costretti a costruire manualmente i tag, ma possiamo limitarci a invocare la funzione render per ognuno degli elementi di complexSource: questa funzione accetta due parametri, rispettivamente, l'oggetto da collegare in binding al template e l'elemento contenitore (target nel nostro caso) all'interno del quale accodare il markup generato. Sicuramente quanto visto finora ci è utile per iniziare a capire come funzionano le logiche di data binding di WinJS; nonostante ciò, tuttavia, si tratta di una tecnica che ben presto tende a mostrare i suoi limiti. Per esempio, non siamo in grado di gestire automaticamente la selezione, né il click sul singolo elemento, tant'è che siamo stati costretti a sfruttare degli hyperlink. Inoltre, nel caso sia necessario supportare lo scrolling, è compito di noi sviluppatori gestirlo, per esempio fissando le dimensioni del contenitore e impostandone lo stile di overflow. Fortunatamente, in WinJS esiste un oggetto più avanzato, che racchiude tutte queste funzionalità insieme a diverse altre, e che sarà l'argomento delle prossime pagine: ListView.