Con l'avvento su scala globale di HTML5 le tecnologie web si sono evolute cercando di offrire all'utente una migliore esperienza applicativa sempre più simile a quella desktop. Sul piano tecnico questo viene realizzato spostando la logica di presentazione sul browser client facendo leva su Javascript e CSS3. In questa sessione vedremo come KnockoutJS, un presentation framework Javascript basato sul pattern Model-View-ViewModel, permette di sviluppare Rich Internet Application (RIA) analizzando le sue caratteristiche implementative e mostrando esempi di casi reali anche in ambito mobile.
3. Agenda
• Knockout JS
– Cosa, Quando, Perché
– Alternative
• Knockout JS: Come
– Oggetti observable
– Attributi data-bind
4. Che cos’è Knockout JS
• Presentation Framework Javascript
– Implementazione di un particolare Design Pattern
di Presentation (UI): il Model-View-ViewModel
(MVVM)
– Implementato completamente in Javascript
– Multi-Browser (che supporti HTML5)
– Convive senza problemi con i maggiori
Framework Javascript (jQuery, jQuery Mobile, …)
– Portale del progetto http://knockoutjs.com
5. Model-View-ViewModel
• Il MVVM fa parte della cosiddetta famiglia
dei presentation pattern MV*
– disaccoppiare i dati rappresentati nella UI
(Model) dalla UI stessa (View) promuovendo
una netta separazione fra questi mediante
l’uso di un oggetto terzo: il ViewModel
6. Model-View-ViewModel
• Si definiscono e si idratano i dati (Model) da
visualizzare
• Si veicolano i dati attraverso il ViewModel verso la
View utilizzando un meccanismo di data-bind
che permetta la gestione bidirezionele degli
aggiornamenti dei dati stessi
• Si definiscono delle operazioni nel ViewModel
per gestire gli eventi provenienti dalla View
7. MVVM e HTML5
• View: il markup HTML
• Model: uno o più oggetti e array Javascript
che contengono solo dati puri e che devono
essere rappresentati nella View
• ViewModel: un oggetto Javascript che
identifica una rappresentazione sotto forma
di codice dei dati (Model) e delle operazioni
della View
8. Knockout JS e MVVM
• Knockout JS si caratterizza principalmente per tre
aspetti:
– Sintassi specifica per la definizione di un binding
dichiarativo dei dati nel markup HTML5
– API Javascript per la definizione delle proprietà
dell’oggetto ViewModel che fornisce un meccanismo
automatico di notifica del loro aggiornamento
– Sintassi di templating di frammenti di markup HTML
per il rendering di liste/array
9. Quando usare Knockout JS
• Knockout JS offre una API in grado di
semplificare e strutturare lo sviluppo di
una logica di UI mediamente complessa
• L’uso di Knockout JS è indicato quando si
affronta lo sviluppo di una Rich Internet
Application (RIA) lato client
10. Perché usare Knockout JS
• Organizzazione della codebase in termini di
responsabilità degli oggetti coinvolti e delle loro
interazioni in modo da evitare il più possibile la
produzione del cosiddetto codice spaghetti
• Gestione strutturata degli elementi e degli
eventi del DOM
• Possibilità di sviluppare il codice utilizzando
facilmente tecniche di Unit Testing
11. Alternative a Knockout JS
• Esistono altri Presentation Framework
Javascript che:
– Si prefiggono gli stessi obiettivi
– Fanno parte della famiglia MV*
• Per citare i più conosciuti:
– BackBone JS
– Ember JS
– Angular JS
12. Knockout JS in 2 minuti
• Definizione di un oggetto ViewModel
Javascript con proprietà observable e
metodi (command)
• Definizione del markup HTML5 con
attributi data-bind
• Applicazione del ViewModel alla View
mediante il metodo ko.applyBindings
14. ViewModel: proprietà osservabili
• Knockout JS offre la possibilità di definire le
proprietà del ViewModel come oggetti osservabili
di tre tipi:
– Observable
– Computed Observable
– Observable Array
• Hanno la capacità di notificare automaticamente
l’aggiornamento del proprio valore alla View e
viceversa
15. Oggetti Observable
• Leggerne il valore:
var fn = self.firstName( );
• Scriverne il valore:
self.firstName("Roberto");
• Chain syntax:
self.firstName("Roberto").lastName("Messora");
• Sottoscrizione esplicita:
self.firstName.subscribe(function(newValue) {
…
});
16. Oggetti Computed Observable
• Definirne la composizione:
self.isMinor = ko.computed(function() {
return self.age() < 18;
});
• Possono essere concatenati:
self.canDrive = ko.computed(function() {
return self.isMinor() == false;
});
• Possono essere anche in scrittura per scenari come:
– Decomposizione dell’input utente
– Convertitore di valore/formato
– Validatore di input utente
• Offrono tutta una serie di metodi e opzioni per un uso avanzato
17. Oggetti Observable Array
• Definirne la composizione:
self.myArray =
ko.observableArray(["a", "b", "c"]);
• Ridefiniscono tutti i classici metodi di un
normale array:
– indexOf, slice
– pop, push, shift, unshift, reverse, sort, splice
– remove, removeAll, destroy, destroyAll
19. Estendere un Observable
• Un oggetto Observable può essere esteso per
fornirne ulteriori funzionalità custom
• Uno degli utilizzi più utili è quello della
validazione delle proprietà del ViewModel
ko.extenders.positiveNumberValidation =
function(target, option) { … };
…
self.age = ko.observable(0).extend({
positiveNumberValidation: "" });
21. View: attributi di data-bind
• Knockout JS offre la possibilità di definire un attributo
di data-bind nei tag del markup HTML5
• Sono disponibili 4 tipi di famiglie di binding:
– Controllo del testo e del rendering:
visible, text, html, css, style, attr
– Controllo del flusso: foreach, if, ifnot, with
– Specifici per i controlli delle form:
click, event, submit, enable, disable, value, hasfocus, ch
ecked, options, selectedOptions, uniqueName
– Custom
22. Sintassi del data-bind
• La sintassi di base è:
data-bind="value: someValue, enable:
isEnabled, …"
• Si possono usare vari tipi di valori:
– Proprietà del ViewModel
– Espressione condizionale
– Chiamata a funzione del ViewModel
– Function expression (funzione inline)
– Object literal (solo con il bindings with)
23. Elementi Virtuali
• I binding di controllo del flusso possono
essere utilizzati anche senza la presenza di
un elemento (tag) contenitore:
<!– ko foreach: items -->
<span data-bind="text: name"></span>
<!-- /ko -->
24. Binding Context
• Il Binding Context è un oggetto che contiene i dati che sono
referenziati nei bindings della View e a cui si può accedere
all’interno degli stessi
• Le proprietà più importanti sono:
– $parent: il ViewModel genitore (se esiste)
– $root: il ViewModel radice
– $data: il ViewModel corrente
– $index: l’indice dell’elemento corrente in un binding foreach
– $element: l’elemento (tag) del markup HTML5 in cui è definito
l’attributo data-bind corrente
26. Custom bindings
• Oltre ai binding built-in nel framework è possibile
crearne di nuovi personalizzati
ko.bindingHandlers.panelVisible = {
init:
function(element, valueAccessor, allBindingsAcces
sor, viewModel) { … },
update:
function(element, valueAccessor, allBindingsAcces
sor, viewModel) { … }
};
…
data-bind="panelVisible: isPanelVisible"
28. Scenari e tecniche avanzate
• In Knockout JS c’è molto di più di quanto visto in
questa presentazione tra cui:
– Un motore di templating del markup HTML5
– Tecniche specifiche di implementazione di librerie
riutilizzabili di custom bindings
– Funzioni helper per la gestione degli eventi scatenati
dagli elementi del markup HTML5
– L’uso del plugin di mapping
– Moltissime funzioni di utility (non documentate…)