Introduzione a Knockout.js

di Andrea Colaci, in HTML5,

Knockout.js è una libreria javascript opensource, studiata per semplificare la realizzazione di interfacce utente complesse, che prevedono anche l'utilizzo di templates.
Questa libreria consente di implementare, in maniera dichiarativa e con una sintassi minimale, tutto il processo di databinding client-side, tipico di diversi scenari web come ad esempio le Single Page Applications (SPA).

In questo articolo vedremo come utilizzare e beneficiare delle funzionalità di Knockout.js e come questa libreria sia facilmente adottabile all'interno di applicazioni pre-esistenti.

Knockout.js è scaricabile dal sito ufficiale con licenza MIT (questo significa che è liberamente utilizzabile e modificabile a patto di includere la licenza stessa nel software) è composta da "semplice" codice javascript senza alcuna dipendenza rispetto ad altre librerie, nei suoi soli 40KB supporta tutti i principali browser (anche alcuni tra i più datati) e, cosa molto importante, vanta una documentazione molto completa e curata. Inoltre questa libreria è inclusa di default in tutti i templates di ASP.NET in Visual Studio (dalla versione 2010).

Knockout.js prevede l'adozione di un Design Pattern molto familiare per gli sviluppatori WPF e Silverlight: Model-View-ViewModel. Questo è di fatto l'unico prerequisito significativo, in quanto l'utilizzo e l'integrazione di questa libreria è molto semplice ed a basso impatto, ma allo stesso tempo consente di risparmiare molto codice ripetitivo di infrastruttura, consentendoci di concentrarci sullo sviluppo di codice più importante riducendo gli errori.

Il Design Pattern Model-View-ViewModel (MVVM)

Lo scopo di MVVM è gestire ed automatizzare interfacce utente di una certa complessità, ricorrendo ad una scomposizione logica dell'interfaccia stessa in 3 elementi funzionali:

  • Model: rappresenta dati e logica di un oggetto che rappresenta una entità, ad esempio i dati di un cliente
  • view-Model: è l'interfaccia funzionale (non grafica) che descrive ed implementa tutte le possibili funzionalità di manipolazione del model (ad esempio il metodo aggiungiIndirizzo() in un ipotetico oggetto cliente). Il ViewModel è indipendente dallo stile e dalla modalità di visualizzazione dei dati, in breve non dovrebbe conoscere nè codice HTML nè CSS.
  • View: è la rappresentazione grafica dello stato del ViewModel, è l'"interfaccia grafica" con cui l'utente può interagire (ad esempio cliccando su un pulsante "Aggiungi Indirizzo")

Il pattern Model-View-ViewModel (MVVM) è spesso l'unica via sensata, oltrechè moderna, per implementare in maniera efficace interfacce utente per la presentazione e la manipolazione dei dati.

MVVM introduce anche tecniche di command bindng (commanding) che consente un maggior disaccoppiamento e astrazione della logica interattiva dell'interfaccia utente.

Per una esaustiva spiegazione del pattern MVVM si consiglia la lettura di: questo articolo

Databinding con Knockout.js

Per iniziare ad apprezzare le funzionalità di questa libreria, è sufficiente inserire una reference alla stessa (disponibile anche via Content Delivery Network).

Nello script che segue, viene illustrato il funzionamento del binding dichiarativo di knockout.js, per associare alla proprietà text di un oggetto span ad una proprietà di un oggetto JavaScript, ricorrendo ad un data attribute (data-bind) in cui viene dichiarata l'espressione di binding.

HTML

<!DOCTYPE html>
<html>
<head>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<meta charset=utf-8 />
<title>Knockout.js intro</title>
</head>
<body>
  <h2>Benvenuto <span data-bind="text: firstName"></span></h2>
  <span>Nome:</span><input type="text" data-bind="value: firstName"/>

 <script type="text/JavaScript">
   
    var viewModel{
        firstName: ko.observable('Andrea')
    }

    ko.applyBindings();
    
  </script>

Commentiamo le istruzioni contenute nello script precedente: nel data attribute, come detto, viene specificata l'espressione di databinding, mentre la proprietà dell'oggetto JavaScript ViewModel è una observable property ovvero una proprietà di cui è possibile sottoscrivere e ricevere le notifiche al variare del valore della stessa.
E' possibile sottoscrivere anche esplicitamente le notifiche, ricorrendo all'istruzione di seguito riportata:

Javascript
    //Sottoscrivo e gestisco la proprietà firstName
    viewModel.firstName.subscribe(function(newValue) {
        alert("Il nome è cambiato: " + newValue);
    });

Con l'istruzione ko.applyBindings(), attiviamo la libreria che processa il DOM attivando tutte le sue funzionalità. I parametri del metodo applyBindings sono opzionali e sono:

  • Il nome dell'oggetto che fungerà da ViewModel
  • La porzione di DOM interessata dal databinding, qualora si desideri una maggiore granularità.

Oltre alle normali proprietà observable, questa libreria offre la possibilità di specificare delle proprietà calcolate e sempre con supporto alle notifiche dei cambiamenti.

Per definire una proprietà calcolata, in grado di sincronizzarsi e ricalcolarsi al variare di alcune proprietà è sufficiente ricorrere a ko.computed come di seguito illustrato

Javascript
function viewModel() {
        var self = this;
      
        self.firstName = ko.observable('Andrea');
        self.lastName = ko.observable('Colaci');
        self.fullName = ko.computed(function() {
           return self.firstName() + " " + self.lastName();
           });  
    };

Abbiamo appena visto come sia semplice, grazie agli observables, gestire il tracking delle proprietà di un singolo oggetto, è altrettanto semplice gestire anche collezioni di oggetti. Uno dei problemi più diffusi, da affrontare durante il rendering di una collezione è la variazione puntuale di uno o più elementi, senza ricorrere ad un "refresh" dell'intera collezione, mossa che potrebbe certamente peggiorare le prestazioni.

Grazie ad observableArray, questo problema è facilmente risolto, in quanto il change tracking viene supportato a livello di singolo elemento, consentendo ad esempio di aggiungere, modificare ed eliminare programmaticamente elementi della lista, senza preoccuparsi di scrivere il codice per gestirne l'aggiornamento (refresh)

Javascript
function viewModel() {
        var self = this;
      
        self.firstName = ko.observable('Andrea');
        self.lastName = ko.observable('Colaci');
        self.fullName = ko.computed(function() {
           return self.firstName() + " " + self.lastName();
           });  
      self.address = ko.observableArray([
          { name: 'Casa', address : 'piazzale Loreto, 5', city:'Milano' , selected:false},
          { name: 'Fatturazione', address : 'corso Buenos Aires, 145', city:'Milano', selected:false},
          { name: 'Spedizione', address : 'viale Amendola, 10', city:'Milano', selected:true}]);
       
    };
2 pagine in totale: 1 2
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Top Ten Articoli

Articoli via e-mail

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

In primo piano

I più letti di oggi

In evidenza

Misc