• Home
  • Perchè dovrei leggere DevBlog?
  • Forum
DevBlog

Da zero a Backbone.js in 30 minuti, visualizzare una collezione di dati

24 novembre 2012 19:35 / 2 Commenti / Mattia

Single page web applications! Backbone.js è una libreria Javascript che permette di semplificare questo pattern di sviluppo. Più in generale, Backbone.js contribuisce all’adozione di un metodo di design delle applicazioni javascript, sfruttando il modello MVP (Model View Presenters), una variante logica del classico Model-View-Controller.

Lo scopo di questo articolo è fornire le basi di utilizzo della libreria, analizzando un esempio pratico. Si vuole visualizzare all’interno di una pagina web l’elenco dei progetti che un ipotetico team di sviluppo ha completato nell’ultimo mese. I requisiti essenziali per proseguire nella lettura sono la conoscenza di:

  • jQuery (1.4 >)
  • Rails (2.3.x >)
  • HTML e Javascript
Per quale motivo Rails? La libreria Backbone.js NON è legata all’ambiente Ruby On Rails e può essere utilizzata in qualsiasi altro ambiente, che utilizzi o meno un framework software. L’esempio proposto in questo articolo è basato su Rails per comodità dello scrittore.

1. La struttura

Il primo passaggio è generare tutti i file che ci servono, per avere un controller, un model e una view con cui lavorare. Dalla console scriviamo:

script/generate scaffold Project title:string description:text
rake db:migrate

Avremo la struttura database funzionante per procedere.

2. Le dipendenze

Ci sono alcune dipendenze da rispettare perchè Backbone.js possa funzionare correttamente. In particolare:

  • Underscore.js ( > 1.3.1) per tutte le operazioni di selezione dati, basic templating, etc
  • json2.js per dinamiche di RESTful persistence, history support con Backbone.Router e DOM manipulation con Backbone.View
  • Framework jQuery ( > 1.4.2) o Zepto.

Lo scaffold precedentemente eseguito ha generato un layout projects.html.erb, all’interno del quale dobbiamo inserire le opportune librerie javascript necessarie:

<%= javascript_include_tag 'jquery-1.8.2.min', 'underscore', 'backbone', 'json2' %>
<%= javascript_include_tag 'application' %>

3. Lato server

Sempre lo scaffold ha generato un ProjectsController che contiene il metodo index così definito:

# GET /projects
# GET /projects.xml
def index
    @projects = Project.all

    respond_to do |format|
        format.html # index.html.erb
        format.xml { render :xml => @projects }
    end
end

La nostra intenzione è quella di leggere dal database la lista dei progetti effettuando una richiesta tramite Backbone.js, e non direttamente dal controller prima del caricamento della View. Pertanto, il nuovo metodo index dovrà essere modificato in questo modo:

  # GET /projects
  # GET /projects.js
  # GET /projects.xml
  def index

    respond_to do |format|
      format.html # index.html.erb
      format.js {
        @projects = Project.all
        render :json => @projects.to_json
      }
      format.xml  { render :xml => @projects }
    end
  end

Nessuna query verrà eseguita, finchè non arriva una richiesta GET sul path /projects.js

4. Parte HTML

Anche il file projects/index.html.erb è stato automaticamente costruito in questo modo dallo scaffold:

<table>
  <tr>
    <th>Title</th>
    <th>Description</th>
  </tr>

<% @projects.each do |project| %>
  <tr>
    <td><%=h project.title %></td>
    <td><%=h project.description %></td>
    <td><%= link_to 'Show', project %></td>
    <td><%= link_to 'Edit', edit_project_path(project) %></td>
    <td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

Il problema è che, al caricamento della pagina, la collezione @projects non esiste più. L’abbiamo rimossa dal metodo index. Il nuovo file projects/index.html.erb si dovrebbe presentare così:

<table class="projects-wrapper">
  <tr>
    <th>Title</th>
    <th>Description</th>
  </tr>
</table>

Notare la proprietà class=”projects-wrapper” aggiunta alla tabella. Ci tornerà utile in seguito.

5. Template javascript

A questo punto, dobbiamo aggiungere al file HTML della index anche una porzione di codice (il nostro template javascript) che rappresenterà ogni nuova riga (ogni Progetto) che verrà aggiunta alla tabella, in modo dinamico, da Backbone.js

Quindi, in fondo alla pagina, scriviamo:

<script type="text/template" id="ProjectLineTpl">
  <td>{{=title}}</td>
  <td>{{=description}}</td>
</script>

6. Finalmente Backbone.js

Questo passaggio è il più importante. Costruiamo il file application.js che conterrà tutta la logica di Backbone.js. Finalmente! Lets dive into it…

Buone norme di programmazione suggeriscono di separare i Model, dalle View e da altre configurazioni software. Per ragioni di spazio in questo esempio semplifichiamo le cose. Per approfondire la questione, fai riferimento a qualsiasi framework di Asynchronous Script Loading.

Backbone.js permette di gestire 3 elementi fondamentali:

  • I Model (rappresentano l’entità da visualizzare. Es: un progetto)
  • Le Collection (rappresentano l’insieme dei Model. Es: un insieme di progetti)
  • Le View (rappresentano le porzioni di DOM dell’intera applicazione)

Nel nostro caso dobbiamo definire:

Il Modello

var Project = Backbone.Model.extend({});

La Collezione
E’ necessario indice qual è il Model gestito dalla collezione e l’URL di riferimento per tutte le operazioni di fetch (recupero) o save (inserimento / aggiornamento) della collazione.

    var Projects = Backbone.Collection.extend({
        model: Project,
        url: '/projects'
    });

La ProjectView
Gestisce la porzione HTML di ogni singola istanza del Model (quindi ogni progetto inserito a database, che verrà recuperato per essere visualizzato a schermo)

    var ProjectView = Backbone.View.extend({
        tagName: 'tr',
        template: _.template($('#ProjectLineTpl').html()),

        render: function(){
            this.$el.append(this.template(this.model.toJSON()));
            return this;
        }
    });

La ProjectsView
Viene utilizzata come wrapper per recuperare il codice HTML dell’intera collezione che è stata costruita, inserirlo sulla posizione finale (la nostra tabella) ed eventualmente proseguire con altri controlli (gestione degli eventi, etc)

    var ProjectsView = Backbone.View.extend({
        el: $('.projects-wrapper'),

        initialize: function(){
            _.bindAll(this, 'render');
            projects.on('reset', this.render);
        },

        render: function(){
            var self = this;

            projects.each(function( project ){
                var p = new ProjectView({
                    model: project
                });

                self.$el.append(p.render().$el);
            });

            return this;
        }
    });

Al termine non rimane che invocare il tutto con le seguenti istruzioni:

    // Chiamata SINCRONA all'URL specificato nella collection, per recuperare i dati (in formato JSON)
    jQuery.ajaxSetup({ async: false });
    projects.fetch();
    jQuery.ajaxSetup({ async: true });

    // Launch start
    var App = new ProjectsView();
    App.render();

Il vero “cuore” pulsante di questa piccola applicazione Backbone.js è rappresentato dall’ultima View (la ProjectsView) perchè innesca l’intero meccanismo di:

  • scansione della Collection
  • creazione delle istanze ProjectView: viene passato 1 parametro che è un oggetto contenente il singolo Project da visualizzare
  • Costruzione dell’HTML del singolo Project (la singola riga della tabella)
  • Aggiunta dell’HTML sopra citato in coda alla tabella

Attenzione! Non esiste un metodo assoluto per raggiungere il risultato che abbiamo appena visto. La logica adottata può essere cambiata e sostituita a piacimento, sfruttando le potenzialità di questa libreria.

Il risultato è una singola pagina web che si occupa, attraverso un po’ di codice Javascript, di leggere dal server e visualizzare una collezione di dati. Pensiamo agli ambiti di utilizzo più complessi: grandi quantitativi di dati che possono essere recuperati un po’ alla volta (la pagina viene costruita in dinamico), inserimento live da parte dell’utente di nuove informazioni, e molto altro.

Scarica il file application.js completo!

Annotazione: Rails è basato su un templating engine chiamato ERB che utilizza, di default, la stessa sintassi di underscore.js per l’output delle variabili (<%= variabile %>). Per usare Backbone.js negli ambienti Rails configurati con ERB evitando conflitti, è necessario inserire questo codice (modificabile a piacimento):

_.templateSettings = {
    interpolate: /{{=(.+?)}}/g,
    evaluate: /{{(.+?)}}/g
};

Altri articoli che potresti trovare interessanti:

  • Come richiamare una funzione PHP tramite Javascript!
  • jQuery Mobile: framework per dispositivi mobili
  • Validare form HTML con jQuery
  • jQuery, un fantastico framework Javascript
  • Pubblicare Redmine su Heroku: guida completa
  • Ruby, perchè usare le dependency injection?
  • Come usare JSON e creare oggetti contenenti diversi data types
  • Rails, associazioni HABTM con un single-select
  • Multi upload di immagini in HTML5 e jQuery
  • Come utilizzare RVM per gestire più versioni di Ruby e Rails
Pubblicato in: JavaScript, Ruby e Rails / Tag: backbone.js, erb, jQuery, MVC, mvp, underscore.js

2 commenti a “Da zero a Backbone.js in 30 minuti, visualizzare una collezione di dati”

  1. Luigi on 25 novembre 2012 at 14:00 said:

    L’argomento é interessante, ma personalmente ho ancora dei punti aperti: fare le view una volta sola, gestire l’autenticazione in sicurezza,.. Spine.js mi piace un po’ di più comunque la parte actionview di rails diventa superata in questi tipo di applicazioni

    Reply↓
  2. Mattia on 25 novembre 2012 at 17:33 said:

    Certo, su applicazioni di questo tipo la libreria ActionView di Rails è inutile. Non ho capito cosa intendi con “fare le view una volta solo”. Per il resto non ho provato Spine.js e un modo per autenticare in sicurezza le chiamate è predisporre una whitelist sui domini abilitati.

    Reply↓

Lascia un Commento Annulla risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation

← Previous Post
Next Post →

Autore

Ciao e Benvenuto sul mio blog!
Mi chiamo Mattia, vivo a Padova.

Sono uno sviluppatore appassionato di software e comunicazione digitale. Questo non è un diario personale, ma uno spazio dove raccolgo informazioni tecniche di programmazione, servizi e strumenti web per sviluppatori.

Articoli recenti

  • Pubblicare codice su WordPress, SyntaxHighlighter Evolved
  • Pubblicare Redmine su Heroku: guida completa
  • Da zero a Backbone.js in 30 minuti, visualizzare una collezione di dati
  • Posizionamento di un sito web nel 2012, quali novità?
  • Imparare a programmare in 10 anni, i consigli di Peter Norvig

Categorie

Tag

.htaccess accessibilità apache api Aruba blog browser business crossbrowser CSS3 dbms editor facebook fondamenti font form geolocalizzazione Google gratis html 5 introduzione jQuery linux Microsoft motori di ricerca newsletter online oop open source ottimizzazione posizionamento programmatore script SEO SERP server sito web software sorgenti tips twitter web 2.0 web designer wordpress xss

Commenti recenti

  • francesco su Creare un social network gratis come Facebook
  • Gian Luca su [PHP] Inviare dati POST senza un form HTML
  • Roberto su Validare form HTML con jQuery
  • claudiot su [C] Divisione per sottrazioni successive
  • gege su Come richiamare una funzione PHP tramite Javascript!

Archivi

  • maggio 2013
  • marzo 2013
  • novembre 2012
  • settembre 2012
  • giugno 2012
  • maggio 2012
  • febbraio 2012
  • dicembre 2011
  • novembre 2011
  • settembre 2011
  • agosto 2011
  • giugno 2011
  • aprile 2011
  • marzo 2011
  • febbraio 2011
  • dicembre 2010
  • novembre 2010
  • ottobre 2010
  • settembre 2010
  • agosto 2010
  • luglio 2010
  • giugno 2010
  • aprile 2010
  • marzo 2010
  • febbraio 2010
  • gennaio 2010
  • dicembre 2009
  • aprile 2009
  • marzo 2009
  • febbraio 2009
  • gennaio 2009
  • dicembre 2008
  • novembre 2008
  • ottobre 2008
  • settembre 2008
  • agosto 2008
  • luglio 2008
  • giugno 2008
  • marzo 2008
  • febbraio 2008

Meta

  • Collegati
  • Voce RSS
  • RSS dei commenti
  • WordPress.org
© Copyright 2013 - DevBlog
Infinity Theme by DesignCoral / WordPress