Programmare con Ajax

IV parte: Ajax e Rails, integrazione e caratteristichedi

Fin dall‘avvento di Ajax nel mondo del Web 2.0, Ruby on Rails ha mostrato un‘interesse particolare per questo nuovo pattern per realizzare applicazioni Web tanto che l‘autore di Prototype (Sam Stephenson) e quello di Script.aculo.us (Thomas Fuchs) hanno subito offerto i loro framework per implementare le funzionalità di Ajax all‘interno di Rails. Ora vediamo brevemente come è caratterizzato Ruby on Rails e come utilizzare le caratteristiche e le invocazioni Ajax attraverso di esso.

Ruby On Rails

Ruby on Rails [1], o più semplicemente Rails, è un ambiente completo per lo sviluppo Web, che contiene al suo interno tutti gli elementi necessari alla realizzazione di siti complessi permettendo di gestire facilmente la creazione di pagine (X)HTML, di accedere facilmente a database, e di integrarvi le funzionalità che caratterizzano le applicazioni web moderne, come le funzionalità Ajax e i Web Service. È un framework di nuova generazione che ha ispirato la nascita di progetti analoghi realizzati con tecnologie differenti, come Cake per PHP [2], Trails  per Java [3], Turbogears [4] e Subway per Python e molti altri.
Osservando Rails nel dettaglio, si scopre che usa tecniche di programmazione già sperimentate e non rivoluzionarie. La potenza di Rails sta nel racchiudere questi meccanismi all'interno di un modello di sviluppo nuovo promettendo di ridurre drasticamente i tempi di sviluppo, abolendo i file di configurazione, automatizzando tutto ciò che è possibile automatizzare, usando dei Domain Specific Language per esprimere con la massima concisione possibile i concetti (un Domain Specific Language è un minilinguaggio adatto a un problema specifico: ad esempio, SQL non è un linguaggio di programmazione pensato per essere usato in qualsiasi situazione, ma allo stesso tempo questo linguaggio è ottimo per il suo scopo specifico, che è quello di fare interrogazioni su database).
Parte del successo di Rails è dovuto al linguaggio con cui è scritto, ovvero Ruby [5], un linguaggio completamente ad oggetti di estrema espressività e potenza,  che riesce a fondere in una sintassi semplice e chiara funzionalità ereditate da Perl, Python, Lisp e Smalltalk.
Le applicazioni Rails utilizzano l'approccio Model-View-Controller, o MVC [6]. Esso permette infatti di raggiungere un ottimo isolamento tra il codice che gestisce i dati e quello che li presenta all'utente, permettendo di estendere e modificare facilmente un'applicazione in qualsiasi momento.
Usando il modello MVC, un'applicazione viene divisa concettualmente in tre parti: model, view e controller. Il model rappresenta gli oggetti del dominio applicativo, siano essi Utenti o Prodotti o Messaggi, insieme a tutte le regole relative ad essi, ad esempio il fatto che un Reparto abbia un solo Direttore e che il Direttore debba essere laureato e così via.
La gestione dell'interazione con l'utente è demandata ai controller, rappresentati dalla libreria ActionController, che si occupa di fornire le funzionalità di alto livello dell'applicazione. Ogni controller è una normale classe, ed ogni metodo pubblico definito in questa classe corrisponde ad un'azione specifica. I controller contengono uno o più metodi pubblici a cui ci si riferisce come azioni. Ogni metodo pubblico di un controller è indirizzabile tramite un URL.
Ad ogni azione definita in un controller corrisponde una view, ovvero ciò che l'utente effettivamente si trova davanti. Le azioni hanno delle viste predefinite che sono utilizzate se l'azione non specifica delle alternative.
Per definire una view con Rails si usano file con estensione .rhtml che contengono delle direttive scritte in Ruby immerse all'interno di codice XHTML, in modo simile a quanto si fa con JSP o PHP. Evidentemente, differenti view possono far uso delle stesse funzionalità fornite da metodi del controller, ad esempio in un sito di informazione è possibile utilizzare una funzionalità che individua le ultime dieci notizie sia per realizzare l'home page sia per realizzare un feed RSS.

Ajax & Rails

Rails ha un semplice e consistente modello per implementare le operazioni Ajax. Una volta che il browser ha restituito e visualizzato la pagina Web iniziale, l'utente può eseguire diverse azioni che possono causare o la visualizzazione di una nuova pagina oppure l'esecuzione di un'operazione Ajax:
l'utente preme un pulsante o un link oppure modifica i dati di una form o di un campo di testo.
I dati associati all'evento scatenato dall'utente sono inviati in maniera asincrona ad un gestore degli eventi sul server tramite l'oggetto XMLHttpRequest.
Il gestore sul server esegue alcune azioni in base ai dati ricevuti e restituisce un frammento HTML come risposta.
Il codice JavaScript sul client viene creato automaticamente da Rails e riceve il frammento di HTML tramite il quale aggiorna la parte specificata della pagina HTML, solitamente il contenuto di un tag

Una richiesta Ajax al server può anche restituire un formato diverso di dati da un frammento HTML.
Rails ha diversi metodi che supportano l'implementazione di richieste Ajax. Uno dei più semplici è link_to_remote(). Si prenda ad esempio una semplice pagina Web che richiede l'ora e che ha un link tramite il quale l'utente effettua la richiesta. Questa applicazione utilizza Ajax attraverso il metodo per recuperare il tempo e mostrarlo nella pagina Web.
Il codice HTML del template di view è:


   
        Ajax Demo
        <%= javascript_include_tag "prototype" %>
   
   
       

What time is it?


       

        I don't have the time, but
        <%= link_to_remote( "click here",
            :update => "time_div",
            :url =>{:action =>:say_when}) %>
            and I will look it up.
       

   

Ci sono due metodi interessanti nel codice qui sopra. Il primo javascript_include_tag include la libreria Prototype. Tutte le features Ajax di Rails usano questa libreria, che è inclusa in Rails.
Il metodo link_to_remote() qui è usato nella sua forma più semplice, con tre parametri:

  1. Il testo da visualizzare per il link, in questo caso "click here".
  2. L'id dell'elemento DOM contenente il contenuto da rimpiazzare con il risultato dell'azione eseguita, in questo caso time_div.
  3. L'URL dell'azione da chiamare sul server, in questo caso, un'azione chiamata say_when.

 

 Figura 1 - Prima di cliccare il link

La classe controller è:

class DemoController < ApplicationController
    def index
    end

    def say_when
        render_text "

The time is " + DateTime.now.to_s + "

"
    end
end

 

Figura 2 - Dopo aver cliccato il link

 

L'action handler index non fa nulla se non permettere a Rails di riconoscere che c'è un'action index e causare la restituzione del template index.rhtml. Il gestore say_when costruisce un frammento di HTML che contiene la data corrente e l'ora. Le Figure 1 e 2 mostrano come appare la pagina index sia prima che dopo aver cliccato il link "click here".

Quando l'utente clicca su questo link, il browser costruisce un XMLHttpRequest, lo invia al server con un URL che invocherà l'handler say_when, il quale a sua volta restituirà il frammento HTML contente il tempo corrente. Il codice JavaScript sul client riceve la risposta e la usa per rimpiazzare il contenuto del tag div con id time_div.
È anche possibile inserire la risposta, invece di modificare il contenuto esistente:

<%= link_to_remote( "click here",
        :update => "time_div",
        :url => { :action => :say_when },
        :position => "after" ) %>

Col parametro opzionale :position => "after" si chiede a Rails di inserire il frammento HTML restituito dal server dopo l'elemento target (time_div). Il parametro position può accettare i valori before, after, top e bottom. Top e bottom permettono l'inserimento dentro l'elemento target, mentre before e after fuori.

 

Figura 3 - L'opzione position inserisce nuovi contenuti

In ogni caso, ora, il link non viene sostituito dalla risposta, ma rimane visibile e può essere "cliccato" più volte ripetendo la richiesta.
La pagina Web non cambia e neppure l'URL mostrato dal browser. In un esempio banale come questo, non ci sono molte vantaggi nel non eseguire un refresh totale della pagina. Le differenze si notano quando si hanno pagine più complesse con più campi da aggiornare.
Il metodo form_remote_tag() è simile al metodo link_to_remote() ad eccezione che esso invia anche il contenuto di un form HTML. Questo significa che l'action handler può usare i dati inseriti dall'utente per formulare la risposta. Questo esempio mostra una pagina Web che visualizza una lista e un form Ajax che permette agli utenti di inserire oggetti alla lista.
Il template di view è il seguente:


   
        Ajax List Demo
        <%= javascript_include_tag "prototype" %>
   
   
       

Add to list using Ajax


        <%= form_remote_tag(:update => "my_list",
                :url => { :action => :add_item },
                :position => "top" ) %>
            New item text:
            <%= text_field_tag :newitem %>
            <%= submit_tag "Add item with Ajax" %>
        <%= end_form_tag %>
       

               
  • Original item... please add more!

  •        

   

Da notare le due parti che definiscono l'inizio e la fine del form. Poiche‘ il form inizia con form_remote_tag() invece di form_tag(), l'applicazione eseguirà la submit utilizzando XMLHttpRequest. I parametri del form_remote_tag() sono:

  • Il parametro update che specifica l'id dell'elemento DOM il cui contenuto dovrà essere modificato dal risultato dell'azione eseguita sul server, in questo caso, my_list.
  • Il parametro url specifica l'azione da chiamare sul server, in questo caso add_item.
  • Il parametro position indica dove inserire il frammento HTML restituito, in questo caso in cima alla lista

 

Figura 4 - Prima di aggiungere un elemento

La classe controller è:

class ListdemoController < ApplicationController
    def index
    end
   
    def add_item
        render_text "
  • " + params[:newitem] + "
  • "
        end
    end

    L'action handler add_item costruisce l'oggetto nella lista in un frammento HTML contenente il testo inserito dall'utente nel campo di testo del form. 

    Figura 5 - Dopo aver aggiunto un po' di oggetti alla lista

    Rails permette anche di monitorare il valore di un campo e di eseguire una chiamata Ajax per un action handler ogni volta che cambia il valore di questo campo. Il valore corrente osservato è inviato all'action handler nel "post data" della chiamata.
    Quando si usa il pattern Ajax per modificare una parte di una pagina Web, l'utente guadagna usabilità e flessibilità. Tuttavia, l'utente perde la possibilità di usare il pulsante indietro dei browser e di inserire la pagina tra i preferiti poiche‘ l'URL non cambia dato che il browser non aggiorna l'intera pagina.
    Il Web ha percorso una lunga strada dai giorni in cui i siti Web erano formati da pagine statiche. Ci si sta lentamente muovendo verso una nuova era in cui i siti sono interconnessi dinamicamente e l'interfaccia per l'utente sta diventando sempre più reattiva e flessibile. Ajax non solo gioca un ruolo importante all'interno del Web 2.0, ma aumenta il numero di persone interessate verso le applicazioni Web.
    Aggiungere caratteristiche tipiche di Ajax in un'applicazione causa un supplemento di lavoro, ma Rails rende questo più semplice.
    Rails permette di realizzare chiamate Ajax in maniera semplice e veloce, riducendo le conoscenze necessarie al programmatore, in quanto con poche righe si possono realizzare funzionalità interessanti senza la necessità di conoscere JavaScript e le caratteristiche dell'oggetto chiave di Ajax, XMLHttpRequest. Con l'evoluzione degli ambienti di sviluppo questo è però possibile ora anche con Java sfruttando le librerie di supporto a JavaScript e Ajax.
    Un altro aspetto da considerare è che, essendo un linguaggio molto più giovane rispetto a Java, ruby on Rails non può avere tutto il supporto che invece ha Java, grazie ai numerosi ambienti di sviluppo che sono nati e che nascono, fornendo sempre maggiori agevolazioni nella progettazione, anche visuale, delle applicazioni.
    Quindi Rails velocizza il lavoro degli sviluppatori, ma la cosa è oggi possibile anche con Java. Col vantaggio però di aver alle spalle tutta una storia di sviluppo di applicazioni Web e non, che Rails invece non ha ancora, e soprattutto un supporto commerciale che questo framework non ha.
    Rails sembra orientato alla creazione e allo sviluppo di applicazioni semplici e poco strutturate, mentre Java sembra avere ancora la meglio per quel che riguarda la progettazione di applicazioni enterprise.

    Conclusioni

    In questo articolo abbiamo cercato di descrivere l'integrazione di Ajax e Rails, che si concretizza con una serie di metodi che possono essere incorporati nel file RHTML relativi alla parte visiva dell'applicazione. Questi metodi di supporto consentono di agganciare dei comportamenti e della logica a elementi DOM utilizzando la stessa sintassi con cui si interagisce con gli oggetti lato server. Il risultato è un file RHTML pulito e coerente e nessun codice JavaScript visibile.

    Riferimenti

    [1] Ruby On Rails
    http://www.rubyonrails.org/

    [2] Cake
    http://www.cakephp.org/

    [3] Trails Framework
    http://www.trailsframework.org/

    [4] Turbogears
    http://turbogears.org/

    [5] Ruby
    http://www2.mokabyte.it/cms/article.run?articleId=7AY-Z26-24S-9N_7f000001_30480431_06fce3e4

    [6] E. Gamma, R.Helm, R. Johnson, J.M. Vlissides, "Design Patterns: Elements of Reusable Object-Oriented Software", Addison-Wesley Professional Computing Series.

    [7] B. Galbraith, D. Almaer, J. Gethland, "Ajax, Guida completa", rgb reference, 2006

    [8]Ajax on Rails
    http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html

    Condividi

    Pubblicato nel numero
    129 maggio 2008
    Lorenzo Bricchi è nato a Faenza (RA) il 14 Aprile del 1981. Si è laureato in Ingegneria Informatica presso l‘università degli studi di Bologna nel marzo del 2007. Ha lavorato per il Gruppo Imola svolgendo attività di consulenza, in particolare su tematiche architetturali e di processo.
    Articoli nella stessa serie
    Ti potrebbe interessare anche