Alloy UI mette a disposizione dello sviluppatore non solo un framework da utilizzare passivamente ma anche un’infrastruttura che può essere estesa aggiungendo i propri moduli personalizzati. Vediamo quindi come fare.
In questo articolo vedremo un aspetto importante di AlloyUI, ossia le possibilità di personalizzazione che mette a disposizione. Infatti non si tratta solo di un framework “bruto”, da utilizzare in maniera proficua ma meccanica. AlloyUI può essere esteso, grazie all’aggiunta di moduli personalizzati, cosa che mostreremo in queste poche righe. Ma, per poterlo fare, occorre prima capire il modo in cui l’infrastruttura di AlloyUI è progettata, e i principi su cui si basa.
Module pattern
Prima di entrare nel vivo della creazione di un modulo per Alloy è necessario fare una piccola introduzione teorica relativa al design pattern su cui si basa l’infrastruttura: si tratta del Module Pattern di Douglas Crockford.
Il Module Pattern sfrutta le closure del linguaggio JavaScript per simulare uno dei principi del paradigma della programmazione a oggetti: l’incapsulamento. Vediamo un esempio di modulo che modella un semplice e generico oggetto Persona:
var person = function() {
// variabili private
var name = “Antonio”;
var birth = new Date(1959, 3, 24);
// metodo privato
function calcAge() {
var today = new Date();
return Math.floor((today – birth) / 31556952000);
}
return {
getName : function() {
return name;
},
getBirth : function() {
return birth.toUTCString();
},
getAge : function() {
return calcAge();
}
};
}(); //
Analisi del listato
Come prima cosa notiamo che l’oggetto viene definito come una funzione; inoltre notiamo anche le 2 parentesi ( ) al termine. Pertanto non solo stiamo dichiarando l’oggetto ma lo stiamo anche istanziando contestualmente.
Dopodiche’ definiamo 2 variabili (di esempio) per memorizzare il nome e la data di nascita della persona; dal momento che sono variabili di una funzione, la loro visibilità è limitata unicamente alla funzione stessa.
Poi definiamo la funzione che calcola l’età (il codice non è di grande interesse); tale funzione sarà privata e pertanto inaccessibile all’esterno.
Infine andiamo a implementare la parte fondamentale del design pattern; come si vede facciamo un return, ma di cosa esattamente?
Sfruttando le closure stiamo restituendo un oggetto JavaScript formato da 3 proprietà che sono a loro volta definite come funzioni (nel caso dell’esempio non hanno parametri, ma è solo un esempio); inoltre tali funzioni possono accedere a variabili e funzioni private.
Utilizzo del modulo
Una volta definito il nostro modulo, possiamo utilizzarlo nel modo seguente:
person.getName(); // restituisce "Antonio" person.getBirth(); // restituisce "Thu, 23 Apr 1959 22:00:00 GMT" person.getAge(); // restituisce "53" person.calcAge(); // da errore, function calcAge is not defined
Definizione sotto Alloy UI
Vediamo ora come definire il modulo all’interno di Alloy UI; a tale proposito create con Eclipse un nuovo progetto portlet attraverso il plugin di Liferay.
Cerchiamo di fare una cosa riutilizzabile e apriamo il file js/main.js; ricordo che tale file è quello che viene creato in automatico da Eclipse e configurato nella portlet come file JavaScript di default (sto parlando dell’elemento footer-portlet-javascript contenuto nel file liferay-portlet.xml). Una volta aperto il file, inseriamo il codice seguente, che di fatto è una rivisitazione di quanto visto in precedenza:
AUI.add( "person-module", function(A) { var name = "Antonio"; var birth = new Date(1959, 3, 24); function calcAge() { var today = new Date(); return Math.floor((today - birth) / 31556952000); } // Prima possibilità, iniettare l'oggetto dentro AUI A.Person = { getName : function() { return name; }, getBirth : function() { return birth.toUTCString(); }, getAge : function() { return calcAge(); } }; // Seconda possibilità, utilizzare il namespace var PersonNS = Liferay.namespace('PersonNS'); PersonNS.getName = function() { return name; }; }, "1.0", { requires: ['aui-base'] } );
Aggiungere il modulo
Per aggiungere il modulo all’infrastruttura di Alloy è necessario utilizzare il metodo add a cui passiamo 4 parametri (gli ultimi 2 sono facoltativi):
- il primo parametro è una stringa che rappresenta il nome del modulo, da ricordare quando dobbiamo usarlo;
- il secondo è invece la funzione che rappresenta l’implementazione del modulo e richiede un unico parametro che è l’istanza dell’oggetto AUI da usare internamente;
- il terzo parametro è il numero di versione del modulo;
- il quarto parametro contiene le dipendenze del modulo e consente ad AlloyUI di caricare correttamente tutta la catena di dipendenze.
Si deve anche notare che manca la coppia di parentesi () finali vista in precedenza; ciò significa che la funzione che crea il nostro modulo non viene eseguita ma solo registrata in Alloy.
Infine l’ultima differenza con il modulo iniziale è che non viene fatto un return della funzione ma un arricchimento dell’oggetto AUI, con il medesimo oggetto che abbiamo restituito prima.
Utilizzo del nuovo modulo
Chiudiamo il file main.js ed apriamo invece la pagina JSP creata in automatico; per poter usare il nostro modulo è sufficiente scrivere:
A.one('#console').append(A.Person.getName() + ' '); A.one('#console').append(A.Person.getBirth() + ' '); A.one('#console').append(A.Person.getAge() + ' '); A.one('#console').append(Liferay.PersonNS.getName() + ' ');
Come possiamo notare il modulo da usare è quello definito in precedenza nel metodo AUI.add ossia person-module; questo fa sì che l’infrastruttura vada a caricare il contenuto del nostro modulo e quindi inietti nell’oggetto AUI la nostra classe Person.
Ovviamente possiamo utilizzare il modulo direttamente in una sandbox di Alloy:
AUI().use('person-module', function(A) { ... });
Conclusioni
In questo breve articolo abbiamo solamente scalfito le potenzialità di estensione dell’inftrastruttura di AlloyUI, che vanno ben oltre quello che è stato presentato. Ma grazie a questa breve introduzione sarà possibile dare una maggiore struttura ai propri progetti fatti con Liferay. Consigliamo ai lettori di dare un’occhiata ai riferimenti riportati qui sotto, per trovare spunti con i quali approfondire questa utilissima possibilità di estensione messa a disposizione da AlloyUI.
Riferimenti
[1] Douglas Crockford
[2] Alloy UI
http://www.liferay.com/community/liferay-projects/alloy-ui/
[3] Alloy UI demo
http://www.liferay.com/community/liferay-projects/alloy-ui/demos
[4] Alloy UI API
http://alloyui.com/deploy/api/
[5] Alloy UI issue tracker
http://issues.liferay.com/browse/AUI