di .NET e di altre Amenità

rss feed 

Sys.UI.Control

Fino a ieri siamo stati abituati a scrivere codice Javascript nelle pagine, cercando di ridurlo ai minimi termini nella profonda convinzione che quanto meno ce ne fosse più probabilità aveva il nostro progetto di funzionare a dovere. Non ho la certezza che voi la pensiate come me, ma so per certo che fino a pochi mesi fa questo era il mio criterio perchè ritenevo che ogni riga di codice Javascript immessa fosse un passo ulteriore verso il baratro dell'entropia nelle mie pagine. Se ben ci pensate in effetti questa sensazione ha un motivo profondo; il codice Javascript ha la caratteristica di "infestare" la pagina di riferimenti, variabili, funzioni e attributi in un modo che in breve la rende pressochè illeggibile. Poco fa ho iniziato la frase sottolineando "Fino a ieri". Infatti, come sto sperimentando in questi giorni alla fine il problema è semplicemente di metodo. E il metodo oggi porta il nome di Microsoft AJAX  Library che tante soddisfazioni mi sta regalando.

Ho trovato ad esempio molto utile l'uso della classe Sys.UI.Control. Questa classe mima le fattezze della più nota System.Web.UI.Control, e consente di creare dei controlli Javascript che vengano associati ad un elemento della pagina. Ad esempio volendo creare un controllo che simuli un Orologio potremmo procedere come segue:

   1: Type.registerNamespace('Elite');
   2:  
   3: Elite.Clock = function(element)
   4: {
   5:     Elite.Clock.initializeBase(this, [element]);
   6:     
   7:     this._timer = null;
   8: }
   9: Elite.Clock.prototype = 
  10: {
  11:     initialize : function()
  12:     {
  13:         this._timer = setInterval(Function.createDelegate(this, this._onInterval), 1000);
  14:         this._writeTime();
  15:         Elite.Clock.callBaseMethod(this, 'initialize');
  16:     },
  17:     dispose : function()
  18:     {
  19:         if (this._timer)
  20:         {
  21:             clearInterval(this._timer);
  22:             delete this._timer;
  23:         }
  24:  
  25:         Elite.Clock.callBaseMethod(this, 'dispose');
  26:     },
  27:     _writeTime : function()
  28:     {
  29:         var element = this.get_element();            
  30:         element.innerText = new Date().toLocaleTimeString();
  31:     },
  32:     _onInterval : function()
  33:     {
  34:         this._writeTime();
  35:     }
  36: }
  37:  
  38: Elite.Clock.registerClass('Elite.Clock', Sys.UI.Control);

Questo breve esempio illustra una classe Javascript che come si vede nelle ultime righe estende Sys.UI.Control. Estendere questa classe implica l'uso di un costruttore con un parametro "element" ovvero un riferimento ad un elemento del DOM ottenuto per mezzo di $get(). Questo elemento deve obbligatoramente essere passato alla classe base con initializeBase(), tenendo presente che l'uso della parentesi quadre [ ] nella chiamata altro non è che la dichiarazione semplificata di un array. initializeBase() infatti concede all'utente di passare un array di parametri per il costruttore della classe base, ma in questo caso siamo limitati sempre e solo a uno.

Il controllo prosegue implementando i metodi initialize e dispose. Il primo che viene chiamato in fase di inizializzazione del controllo è ereditato dalla classe base e si incarica di istanziare oggetti, agganciare eventi e fare sostanzialmente tutte quelle attività che allocano risorse. In particolare in questo caso si alloca un timer che notifica alla classe il trascorrere dei secondi e poi passa il controllo alla classe base.

Nel metodo dispose, ereditato dalla classe base che implementa Sys.IDisposable (non ci si fa mancare nulla... anche le interfacce!), ovviamente si provvede a disallocare tutte le risorse. Questa attività è di fondamentale importanza. nonostante ci troviamo in un ambiente "protetto", all'interno del browser, i memory leak sono quanto di più frequente possiamo immaginare. Ecco perchè disallocare tutto nel metodo dispose è l'unico modo realmente sicuro di garantire lunga vita alla nostra pagina e con lei alla finestra del browser...

Diversamente da quello che ci si può aspettare per instanziare questo controllo non è sufficiente usare "new". Per inizializzare correttamente il controllo e per fare in modo che al suo rilascio ne venga invocato il metodo dispose è opportuno usare Sys.Component.create o il suo più comodo shortcut $create():

   1: var clock = $create(Elite.Clock, {}, {}, null, $get('redClock'));
   2: clock.addCssClass('myRedClock');

In questo esempio si istanzia il controllo passando poi una classe css che darà ad esso l'aspetto voluto. addCssClass() è solo uno dei metodi utili che si possono reperire nella classe e nella gerarchia a cui fa capo.

In breve quello che si ottiene è riportato nello screenshot qui a sinistra. Una volta realizzata la classe sarà molto semplice usarla anche più volte nella medesima pagina associando ad essa gli stili e le caratteristiche grafiche che più desideriamo per renderlo consono alle nostre esigenze.

 Ricordiamo però che Sys.UI.Control richiede un elemento del DOM in ingresso e quindi non solo uno <span> o un <div> ma anche un qualsiati tag html finanche il <body> che possiamo raggiungere facilmente con la proprietà document.body. Proprio in questi giorni mi sono avvalso di questa tecnica per realizzare una classe che al pari della classe C# di Code Behind rappresenti gli elementi costitutivi della pagina. La comodità sta nel fatto che pressochè ogni chiamata può migrare dall'essere immersa nell'HTML a diventare un event handler nella classe stessa.

Se poi siete anche arditi potreste permettervi di adottare l'ereditarietà per creare una classe Javascript base per diverse pagine molto simili tra loro ma che applichino la logica in modo solo leggermente diverso. Questa tecnica che tipicamente si usa tra diverse pagine ASPX nel file .cs ora è perfettamente disponibile anche in Javascript e sostanzialmente ci consente di scrivere quello che potremmo definire come un code-behind client-side.

Inutile dire che ogni giorno che passa sono sempre più affascinato da questa libreria. In realtà, nonostante le premesse di questo post, amo particolarmente Javascript mediante il quale ho scritto delle applicazioni molto belle, ma dopo aver provato la Microsoft AJAX Library ne sono inguaribilmente affezionato... e attenzione perchè con silverlight e il Framework 3.5 le cose saranno anche meglio!

Technorati tags: , ,
Edit
---

Comment so far

Feedback

  1. Matteo Migliore  2007-08-31T00:59:54+01:00 | 

     re: Sys.UI.Control
    Che dire... anche a te, complimenti per queste serie di post/articoli molto interessanti. Grazie :-).


Title  
Name  
Email
Url
Comment   
Please add 4 and 2 and type the answer here: