3 pagine in totale: <<Indietro 1 2 [3]
Lo scheletro del controllo
Poichè il controllo con vista a tab verticali non apporta nuove funzionalità ad elementi esistenti del DOM, ma da esso stesso l'identità ad un elemento, la scelta sul tipo da cui derivare lato client la nostra classe cade obbligatoriamente su Sys.UI.Control. Una volta presa questa decisione architetturale, è possibile dare vita alla prima bozza del controllo:
Type.registerNamespace('Cobisi');
Cobisi.TabViewContainer = function(element)
{
Cobisi.TabViewContainer.initializeBase(this, [element]);
};
Cobisi.TabViewContainer.prototype =
{
initialize : function()
{
Cobisi.TabViewContainer.callBaseMethod(this, 'initialize');
// TODO: Inizializzazione del controllo
},
dispose : function()
{
// TODO: Cleanup del controllo
Cobisi.TabViewContainer.callBaseMethod(this, 'dispose');
}
};
Cobisi.TabViewContainer.registerClass('Cobisi.TabViewContainer', Sys.UI.Control);
Come è possibile notare dal listato, il costruttore della classe Sys.UI.Control attende il parametro element, a sua volta utilizzato dal costruttore del controllo in corso d'opera: si tratta di un riferimento ad un elemento del DOM, a cui si desidera che l'istanza dell'oggetto sia associata. Tale parametro è obbligatorio.
Il metodo initialize(), ereditato da Sys.Component e richiamato dal framework, permette di inizializzare l'istanza del controllo, mentre dispose() effettua l'operazione inversa, liberando eventualmente risorse. Chiaramente l'oggetto può solo vivere all'interno del browser, di conseguenza le risorse da rilasciare non sono altro che array particolarmente voluminosi e, in particolar modo, i gestori di evento: è noto, infatti, che alcuni browser non gestiscono correttamente l'allocazione di memoria per i gestori di evento e, se questi non vengono rilasciati esplicitamente, producono memory leak, con un conseguente degrado delle performance.
Il successivo obiettivo consiste nell'associare a ciascun elemento HTML che rappresenta un'etichetta di tab, un gestore per gli eventi di mouseover e mouseout: il primo si occupa di predisporre il timeout di visualizzazione del contenuto del tab corrente, il secondo di annullare un eventuale timeout non ancora scaduto (ovvero, se il puntatore entra in un'area di un'etichetta e poi vi esce prima che sia trascorso il delay di 200 millisecondi, l'operazione di visualizzazione del tab viene annullata).
Chiaramente, per poter associare gli eventi menzionati, è necessario disporre dei riferimenti agli elementi del DOM di interesse. Fortunatamente, la classe Sys.UI.Control, da cui si è scelto di far derivare il controllo in costruzione, mette a disposizione il metodo get_element() e get_id(), in grado di ritornare, rispettivamente, l'elemento HTML a cui il controllo è associato e l'identificativo dello stesso.
Organizzazione interna del controllo
Pur tuttavia, non essendoci alcun evento da associare direttamente all'elemento DOM contenitore (vedi figura 2), tali metodi possono avere in tal caso un'utilità solo marginale; poichè gli eventi di mouseover e mouseout sono associati alle singole etichette dei tab, è infatti necessario ottenere un riferimento a tutti gli elementi HTML tramite cui queste si manifestano. Per ottenere tale risultato è necessario ideare una strategia che ne consenta il recupero.
La strategia, scelta tra molte disponibili, consiste nell'assegnare a ciascuna etichetta, all'atto del rendering del markup (lato ASP.NET sul server), un identificativo composto da quello del controllo contenitore (proprietà ClientID), un carattere discriminante di cui a breve sarà chiaro lo scopo ed un numero progressivo. Condivisa questa convenzione con la classe JavaScript, è possibile recuperare facilmente gli elementi di interesse.
In realtà le tipologie di elementi da recuperare sono due: alle etichette si devono infatti aggiungere i pannelli dei contenuti, da rendere visibili (o invisibili) a seconda dell'attivazione del relativo tab. Anche in questo caso viene comodo riutilizzare la strategia di nomenclatura sopra esposta, facendo uso del carattere discriminatore: un particolare valore corrisponde infatti ad un'etichetta (L, iniziale di Label), un altro ad un pannello di contenuto (C, iniziale di Content). Una volta effettuato il rendering, la struttura del markup acquisisce di conseguenza un aspetto simile a quello visibile in figura 4.
Figura 4 - Struttura del markup
Una volta poste le basi della metodologia di recupero degli elementi di interesse, è possibile creare una funzione in grado di recuperare un tab - inteso come coppia dei controlli etichetta e pannello di contenuto - dato l'indice dello stesso.
Il codice del metodo, cuore di tutto il controllo, è quello del listato che segue:
_getTab: function(tabIndex)
{
var ctrlLabel = $get(String.format('{0}_L{1}', this.get_id(), tabIndex));
var ctrlContent = $get(String.format('{0}_C{1}', this.get_id(), tabIndex));
if (ctrlLabel && ctrlContent)
return {
Label: new Sys.UI.Control(ctrlLabel),
Content: new Sys.UI.Control(ctrlContent),
Index: tabIndex
};
return null;
}
È conveniente notare che il carattere underscore (_) anteposto al nome del metodo è stato inserito perchè tale membro non è pubblico; poichè in JavaScript non esiste il concetto di incapsulamento, si è seguita la convenzione stabilita dagli sviluppatori ASP.NET AJAX, consistente per l'appunto nell'anteporre tale carattere al nome di ciascun membro non pubblico delle proprie classi.
Richiamare la funzione $get() è un modo più veloce di richiamare la funzione getElementById() della classe Sys.UI.DomElement: Microsoft ha infatti creato una serie di funzioni scorciatoia (shortcut) come questa per alcuni tra i metodi più utilizzati della libreria JavaScript. La classe DomElement rappresenta un particolare elemento del DOM e consente di manipolare tale elemento con semplicità; inoltre, poichè gli utilizzatori di _getTab() potrebbero trarre beneficio dall'ulteriore semplicità di gestione della classe Sys.UI.Control, si è scelto di avvalersi di questa classe per la costruzione dell'array associativo ritornato al chiamante.
Una volta definita la funzionalità di recupero dei tab, è possibile ritornare a concentrarsi sugli eventi che governano il controllo a runtime.
La prima parte dell'articolo termina qui. Nella seconda parte viene proposto e completato lo studio dettagliato del controllo ASP.NET AJAX introdotto in quest'articolo, documentato e commentato in ogni passaggio di interesse.
3 pagine in totale: <<Indietro 1 2 [3]
Attenzione: Questo articolo contiene un allegato
Contenuti dell'articolo
Per inserire un commento, devi registrarti alla nostra community.






Difficoltà
Contenuti
Stampa
Download


