Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Creare applicazioni con Ember.js

Sviluppare applicazioni Web e Mobile innovative con Ember.js, framework nato dalla costola di SproutCore, molto utilizzato in alcuni progetti Apple
Sviluppare applicazioni Web e Mobile innovative con Ember.js, framework nato dalla costola di SproutCore, molto utilizzato in alcuni progetti Apple
Link copiato negli appunti

Se agli inizi della sua carriera JavaScript aveva un ruolo quasi decorativo, limitandosi ad aggiungere interattività alle pagine Web, nel corso degli anni il suo ruolo è cresciuto consentendo di creare pagine Web sempre più sofisticate. Oggi il ruolo di questo linguaggio nel Web, e non solo, ha assunto un'importanza tale da consentire di realizzare delle vere e proprie applicazioni, che richiedono dunque competenze tipiche di chi sviluppa software in modo professionale.

Ne è testimonianza la nascita di framework come Backbone.js o Knockout.js, che mettono a disposizione dello sviluppatore pattern e funzionalità sempre più vicini a quelli dei moderni linguaggi di programmazione.

Ember.js si inserisce in questo contesto offrendo un ricco insieme di funzionalità che consentono non di scrivere semplici script, ma di progettare ed implementare veri e propri client Web.

Il framework Ember.js

Anche se la nascita di questo framework è relativamente recente, esso affonda le sue radici in SproutCore, un progetto nato nel 2007 e molto utilizzato in alcuni progetti da Apple. Ha quindi una base di codice consolidata che garantisce una certa stabilità.

L'obiettivo di Ember.js viene descritto sulla home page del progetto stesso: un framework per creare applicazioni web ambiziose. Ed in effetti le funzionalità messe a disposizione dello sviluppatore sono notevoli.

Supporta il pattern MVC ed integra JavaScript con un modello ad oggetti che si avvicina a quelli dei linguaggi orientati agli oggetti, con la possibilità di definire classi, di eseguire l'override di proprietà e metodi, di creare sottoclassi, di creare proprietà calcolate e observer, di definire binding tra due proprietà. Supporta anche un meccanismo di creazione di namespace e prevede un sofisticato template engine basato su mustache.js.

In questo articolo esploreremo l'approccio alla programmazione proposto da Ember.js e metteremo alla prova le sue principali funzionalità implementando una semplice applicazione che visualizza i tweet di HTML.it.

Setup del progetto Ember.js

Per iniziare scarichiamo lo starter kit a partire dalla home page del progetto. Si tratta di uno zip contenente tutto l'occorrente per partire con Ember.js, in particolare contiene una pagina HTML d'esempio con il classico Hello world!.

Analizzando la pagina HTML vediamo le seguenti inclusioni:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="js/libs/ember-0.9.8.1.min.js"></script>
<script src="js/app.js"></script>

Come possiamo notare, Ember.js dipende da jQuery ed è pertanto necessario includere prima questa libreria. L'ultima inclusione riguarda il file app.js che conterrà il codice JavaScript dell'applicazione che realizzeremo.

Definizione dell'applicazione

Per realizzare il nostro esempio guida, definiamo come prima cosa l'applicazione nel file app.js:

var HTMLitTweets = Ember.Application.create();

Da questa riga di codice appare chiaro come il framework metta a disposizione l'oggetto globale Ember, abbreviabile anche con Em, che fornisce tutte le funzionalità accessibili da JavaScript.

Nel caso specifico abbiamo creato un'istanza di applicazione chiamandola HTMLitTweets. Questa istanza è la base che ci consente di creare il resto della nostra applicazione e che funge da namespace per evitare collisioni di nomi con eventuali altri elementi. Un requisito importante sul nome dell'applicazione è che inizi con una lettera maiuscola in modo che il sistema di binding la possa individuare come root all'interno di un percorso gerarchico.

In fase di creazione dell'applicazione possiamo effettuare delle impostazioni particolari, come definire delle proprietà, dei metodi o gestire l'evento ready, come mostrato nel seguente esempio:

var HTMLitTweets = Ember.Application.create({
  version: '1.0',
  ready: function() {
    alert('Eccomi!');
  }
});

In questo caso abbiamo definito la proprietà version assegnandole il valore 1.0 ed abbiamo gestito l'evento ready visualizzando un messaggio. La gestione dell'evento ready è analoga all'uso del metodo ready() di jQuery ed ha lo scopo di assicurarci che il DOM e l'infrastruttura messa a disposizione da Ember.js siano stati completamente caricati dal browser.

Definizione del modello (model MVC)

Abbiamo detto che Ember.js supporta il pattern MVC per la realizzazione di applicazioni. Vediamo in che termini affrontando la definizione del model della nostra applicazione. In pratica, gli oggetti che andremo a gestire sono rappresentati dai tweet di HTML.it. Definiamo la classe dei tweet nel seguente modo:

HTMLitTweets.Tweet = Ember.Object.extend({
  name: null,
  avatar: null,
  text: null,
  date: null
});

Notiamo come la definizione viene creata come un elemento all'interno del namespace della nostra applicazione. Il metodo extend() di Ember.Object consente di definire una classe specificando le proprietà ed i metodi previsti. I valori assegnati alle proprietà rappresentano i valori di default.

Nel nostro caso abbiamo definito un tweet come un oggetto che presenta il nome dell'utente, l'immagine usata come avatar, il testo del tweet e la data e ora di pubblicazione.

La creazione effettiva di un'istanza di questa classe verrà effettuata utilizzando il metodo create() ereditato da Ember.Object, come avremo modo di vedere più avanti.

Una interessante caratteristica di Ember.js è la possibilità di definire una classe in passi successivi.

In altre parole, è possibile aggiungere o ridefinire proprietà e metodi di una classe in qualsiasi punto della nostra applicazione usando il metodo reopen(). Ad esempio, il seguente codice aggiunge la proprietà followers_count alla definizione di tweet data sopra:

HTMLitTweets.Tweet.reopen({
  followers_count: 0
});

Definizione del controller

La classe che abbiamo definito ci consente di descrivere un singolo tweet, ma la nostra applicazione deve visualizzare l'elenco degli ultimi tweet pubblicati. In altre parole, abbiamo bisogno di una struttura che ci consenta di gestire un elenco di oggetti da visualizzare in una view.

Per questo scopo possiamo utilizzare un ArrayController:

HTMLitTweets.tweetsController = Ember.ArrayController.create({
  content: []
})

L'ArrayController mette a disposizione la proprietà predefinita content destinata a contenere i tweet. Nel nostro caso abbiamo inizializzato la proprietà con un array vuoto. Per caricare i tweet di HTML.it in questa struttura creiamo il metodo loadTweets():

HTMLitTweets.tweetsController = Ember.ArrayController.create({
    content: [],
    loadTweets: function() {
      var self = this;
	  $.getJSON('http://api.twitter.com/1/statuses/user_timeline.json?screen_name=h_htmlit&callback=?',function(data){
	      self.set('content', []);
		  $(data).each(function(index,value){
		      var t = HTMLitTweets.Tweet.create({
			      avatar: value.user.profile_image_url,
				  name: value.user.name,
				  text: value.text,
				  date: value.created_at
			  });
		      self.pushObject(t);
		  })
      });
    }
})

Analizziamo il codice per capire come avviene il caricamento dei tweet. La funzione sfrutta le API di Twitter per ottenere un elenco di oggetti JSON che rappresentano i tweet di un dato utente. Una volta ottenuto l'elenco, per ciascun oggetto viene creata un'istanza della classe HTMLitTweets.Tweet ed assegnati i valori alle rispettive proprietà. Quindi il nuovo oggetto appena istanziato viene aggiunto alla proprietà content tramite il metodo pushObject() dell'ArrayController.

Naturalmente vorremmo che il caricamento dei tweet avvenisse non appena l'utente accede alla pagine dell'applicazione, quindi andiamo a modificare la gestione dell'evento ready dell'applicazione:

var HTMLitTweets = Ember.Application.create({
    version: '1.0',
    ready: function() {
        HTMLitTweets.tweetsController.loadTweets();
    }
});

View e Handlebar

Concentriamoci ora su come visualizzare i tweet sulla pagina HTML. Come in qualsiasi applicazione basata sul pattern MVC, una view è un elemento dell'interfaccia con cui l'utente può interagire.

Per definire una view, Ember.js mette a disposizione dello sviluppatore un sistema di templating per la definizione dichiarativa di un elemento dell'interfaccia utente. Ad esempio, per inserire sulla pagina HTML della nostra applicazione l'elenco dei tweet possiamo definire un template analogo al seguente:

<script type="text/x-handlebars">
<ul class="tweets">
{{#each HTMLitTweets.tweetsController}}
<li class="tweet">
<img {{bindAttr src="avatar"}} />
<span>{{date}}</span>
<h3>{{name}}</h3>
<p>{{text}}</p>
</li>
{{/each}}
</ul>
</script>

Notiamo innanzitutto che il nostro template è incluso in un blocco <script> il cui tipo è text/x-handlebars. Specificando un tag <script> di questo tipo consente a Ember.js di individuare il template e di predisporre le risorse necessarie per la sua elaborazione.

Il framework infatti ha un template engine chiamato Handlebars che utilizza una sintassi derivata da mustache.js: le espressioni che devono essere elaborate dal sistema sono racchiuse tra doppie parentesi graffe. L'espressione:

{{#each HTMLitTweets.tweetsController}}

indica un ciclo di elaborazione da eseguire per ciascun oggetto contenuto nell'ArrayController specificato. All'interno del ciclo indichiamo come e dove visualizzare il valore delle proprietà di ciascun oggetto HTMLitTweets.Tweet.

Questa definizione crea un vero e proprio binding tra le proprietà del nostro modello e la view, pertanto ogni variazione del valore delle proprietà verrà automaticamente riportato sull'interfaccia utente.

Se vogliamo associare il valore di una proprietà all'attributo di un tag invece che al suo contenuto occorre fare uso di bindAttr. È questo infatti l'approccio che abbiamo adottato per definire il binding tra la proprietà avatar dell'oggetto e l'attributo src del tag <img>.

A questo punto dell'implementazione la nostra applicazione è in grado di visualizzare gli ultimi tweet di HTML.it con una schermata analoga alla seguente:

Interazione con l'utente

Naturalmente per completare il tutto occorre consentire una certa interattività all'utente, ad esempio per consentirgli di andare direttamente all'articolo segnalato dal singolo tweet cliccando sul relativo elemento.

Implementiamo questa funzionalità collegando la view con il metodo gotoArticle() che andremo ad implementare nel nostro controller HTMLitTweets.tweetsController. Per attivare questo collegamento modifichiamo il template della nostra view aggiungendo una nuova espressione in corrispondenza dell'elemento <li>, come mostrato di seguito:

<li class="tweet" {{action "gotoArticle" target="HTMLitTweets.tweetsController"}}>

In questa espressione specifichiamo l'azione che dovrà essere eseguita in corrispondenza del clic sull'elemento della lista, indicando il metodo e, tramite target, il controller a cui questo appartiene.

Non ci resta che aggiungere il metodo gotoArticle() al controller HTMLitTweets.tweetsController:

gotoArticle: function(view) {
   var liElement = $(view.target);
   document.location.href = getURL(liElement.find('p').text());
}

Il metodo riceve come parametro la vista corrente, la cui proprietà target ci consente di accedere all'elemento che ha intercettato il clic. La funzione getURL() estrae l'URL dell'articolo dal testo del tweet e vi reindirizza il browser.

Conclusioni ed approfondimenti

Il codice completo dell'applicazione, integrato con l'aggiornamento automatico degli eventuali nuovi tweet, è disponibile in allegato all'articolo.

Naturalmente l'applicazione che abbiamo implementato in questo articolo ha uno scopo didattico, per introdurre l'approccio allo sviluppo con Ember.js, il framework prevede numerose altre possibilità che per esigenze di spazio non abbiamo potuto affrontare in questa sede. Il sito del progetto, comunque, mette a disposizione una ricca documentazione ed alcune guide oltre al reference delle API del framework.

Link utili

Ti consigliamo anche