- Learn
- Guida Titanium
- Data Binding dei Modelli
Data Binding dei Modelli
In questo capitolo modificheremo l’app della lezione precedente per introdurre il concetto di data binding, cioè il collegamento dei dati tra l’interfaccia utente e la logica applicativa. Creeremo una nuova finestra, contenente una TableView collegata ad una collezione Alloy. La nostra app ci consentirà di selezionare una riga dalla tabella, in modo da utilizzare i dati in essa contenuti per valorizzare i campi di una schermata.
index.xml e index.tss
Modifichiamo prima di tutto la vista index.xml, per aggiungere ad essa un nuovo pulsante elenco. Tramite quest’ultimo apriremo la lista dei libri in una nuova finestra.
<Alloy>
<Window class="container" layout="vertical">
<TextField id="title" hintText="Titolo" top="40" class="text" />
<TextField id="author" hintText="Autore" top="10" class="text"/>
<TextField id="isbn" hintText="ISBN" top="10" class="text"/>
<Button id="save" top="10" title="salva" class="button" onClick="save"></Button>
<View top="10" height="Ti.UI.SIZE">
<Button id="prev" left="10" title="precedente" class="button" onClick="prev"></Button>
<Button id="next" right="10" title="successivo" class="button" onClick="next"></Button>
</View>
<Button id="list" top="10" title="elenco" class="button" onClick="list"></Button>
</Window>
</Alloy>
Anche il file dello stile, index.tss, cambia leggermente. Modificheremo infatti la dimensione dei pulsanti affinchè occupino solo l’ampiezza strettamente necessaria per essere disegnati (utilizzeremo la costante Ti.UI.SIZE).
".button": {
height: "40",
width: Ti.UI.SIZE,
borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
}
Ci occorre ora aggiungere una nuova funzione di callback, che chiameremo list()
;
ma prima di scriverla creiamo un nuovo controller con lo stesso nome. Una
volta creatolo, apriamo il file list.xml e
modifichiamone il contenuto.
list.xml
<Alloy>
<Collection src="book" />
<Window class="container" backgroundColor="white" onClose="close" onClick="exit">
<TableView dataCollection="book" onClick="show" height="80%">
<TableViewRow title="{title}" alloy_id="{alloy_id}" />
</TableView>
</Window>
</Alloy>
Il tag Collection ha lo scopo di mostrare una collezione book (quella che avevamo definito nel file app/models/book.js nella lezione precedente), mentre l’attributo dataCollection utilizzato nel tag TableView esprime il collegamento (data binding) tra la collezione e la tabella. Da questo punto in avanti, usando una notazione con le parentesi graffe, potremo far riferimento ai singoli attributi di un modello tratto dalla collezione book. La riga della tabella, infatti, avrà come titolo il valore ricavato dall’attributo title del modello.
L’attributo alloy_id, invece, esprime una chiave univoca che viene associata a ciascun modello all’atto del salvataggio. Useremo questa chiave per poter selezionare un modello della collezione senza dover scorrere gli elementi come avveniva nel’app della lezione scorsa.
list.js
Il controller list.js conterrà le definizioni delle tre callback
show
, exit
e close
, e si occuperà
di passare il modello selezionato alla finestra in background,
utilizzando una callback passata come argomento da index.js.
Prima di tutto, il controller riceverà la callback come argomento, e popolerà i valori della collezione dentro la TableView attraverso il metodo fetch().
var args = arguments[0] || {};
var callback = args.onRowClickCallback;
Alloy.Collections.book.fetch();
La funzione exit()
servirà invece per chiudere la finestra una volta
selezionato un libro, che sarà arrivato anche
cliccando su un’area bianca al di fuori della tabella. Quando si
chiama il metodo close()
su un oggetto Ti.UI.Window,
quest’ultimo genererà un evento close
(gestibile con l’attributo onClose) che noi utilizzeremo per liberare la
memoria.
La funzione close()
sarà quindi la callback che verrà
eseguita alla chiusura della finestra. Il comando $.destroy
libererà la memoria occupata dalla collection e dal sistema di
data binding. È bene non dimenticare di eseguire questa operazione, per evitare che la memoria si esaurisca velocemente con l’utilizzo dell’app.
function exit()
{
// chiudo la finestra
$.list.close();
}
function close() {
// da chiamare per evitare memory leaks
$.destroy();
};
A questo punto si definisce la callback show()
, che verrà
associata al click su una riga della tabella, per selezionare
il libro di cui vogliamo ottenere i dati precedentemente
salvati.
function show(e) {
// mostro il valore di e nella console
Ti.API.info(JSON.stringify(e));
// mostra il modello attuale nella finestra sottostante
callback && callback(e.row.alloy_id);
// chiudi la finestra
exit();
};
La funzione show()
chiama la funzione di callback
passandole l’attributo alloy_id, che identifica univocamente
un modello all’interno di una collezione. La definizione
della funzione di callback è scritta nel
controller chiamante, ovvero index.js,
index.js
Le modifiche al sorgente di index.js sono prevalentemente
due: la callback list()
che apre la finestra con l’elenco
dei libri, e la callback che viene chiamata da list.js per
visualizzare il libro selezionato.
Analizziamo la chiamata alla callback list()
:
function list() {
var list = Alloy.createController('list', {
onRowClickCallback : showModelWithID
}).getView();
list.open();
}
In questa chiamata viene creato il controller list, e viene passato come argomento un oggetto che contiene una coppia chiave-valore, come il seguente:
{
onRowClickCallback : showModelWithID
}
onRowClickCallback è il nome dell’attributo che ha come valore il riferimento alla funzione showModelWithID, che sarà quindi la funzione di callback che verrà chiamata in list.js quando selezioniamo un libro dalla tabella.
La definizione della funzione showModelWithID (e di quelle ad essa correlate) è la seguente:
function showModel(index) {
var model = books.at(index);
displayModel(model);
}
function showModelWithID(id) {
var model = books.get(id);
displayModel(model);
}
function displayModel(model) {
Ti.API.info(JSON.stringify(model));
$.title.value = model.get("title") || "";
$.author.value = model.get("author") || "";
$.isbn.value = model.get("isbn") || "";
}
In pratica la funzione showModel
della lezione precedente viene
utilizzata come base per la definizione di showModelWithID
. La
differenza è che mentre la prima estraeva un modello dalla
collezione usando un indice numerico, quest’ultima
lo estrae utilizzando la sua chiave univoca.
Entrambe, ottenuto il modello, chiameranno la funzione displayModel
per
visualizzare il libro selezionato.
Validare l’input
Nella scorsa lezione abbiamo accennato al fatto che è possibile definire delle funzioni di validazione per il modello. Nell’app che stiamo costruendo, immaginiamo che sia obbligatorio compilare i campi titolo ed autore. La funzione di validazione si può definire estendendo il modello, aggiungendo la callback associata all’attributo validate nel file app/models/book.js.
extendModel : function(Model) {
_.extend(Model.prototype, {
// extended functions and properties go here
validate : function(attrs) {
var title = attrs["title"];
var author = attrs["author"];
if (title.length Per richiamare il validatore appena definito, basta chiamare la funzione
isValid() sul
modello che vogliamo salvare. Nel caso della funzione save()
di index.js, la dovremo applicare sulla variabile book.
[code lang=javascript]
// Crea un modello di tipo 'book'
var book = Alloy.createModel('book', {
title : $.title.value,
author : $.author.value,
isbn : $.isbn.value
});
if (!book.isValid())
{
alert("titolo o autore mancanti");
return;
}
Il codice sorgente degli esempi utilizzati in questo articolo è allegato a questo articolo, nonchè disponibile su GitHub.
Se vuoi aggiornamenti su JavaScript, mobile inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
I Video di HTML.it
Larry Wall spiega le basi della programmazione
Larry Wall, creatore del linguaggio di programmazione PERL, spiega le basi della programmazione per principianti a chi si affaccia per […]