Condividi tramite


Creazione di controlli client AJAX personalizzati

Aggiornamento: novembre 2007

In questo argomento viene illustrato come creare un controllo client AJAX ASP.NET e utilizzarlo in una pagina. In particolare, vengono illustrate le seguenti operazioni:

  • Utilizzare il modello di progettazione del prototipo in ECMAScript (JavaScript) per definire una classe di controllo.

  • Registrare un controllo come classe derivata dalla classe di base Sys.UI.Control.

  • Inizializzare la classe di base Control e richiamarne i metodi.

  • Creare eventi personalizzati che uno sviluppatore della pagina può associare e gestire.

  • Utilizzare il controllo client in una pagina ed eseguire l'associazione agli eventi del controllo.

Viene fornito un esempio di un controllo client completo che crea un pulsante con comportamento al passaggio del mouse.

Questo argomento è incentrato sui controlli client. Sono disponibili tre tipi di oggetti del componente client ASP.NET AJAX:

  • Componenti non visivi che derivano dalla classe di base Sys.Component e che non dispongono della rappresentazione dell'interfaccia utente.

  • Comportamenti che derivano da Sys.UI.Behavior.

  • Controlli che derivano da Control.

Nella tabella riportata di seguito viene fornito un riepilogo delle differenze tra componenti, comportamenti e controlli.

Tipi di oggetti del componente client

Riepilogo

Componenti

  • Derivano dalla classe di base Component.

  • In genere non dispongono di una rappresentazione dell'interfaccia utente, ad esempio un componente Timer che genera eventi a intervalli ma non è visibile nella pagina.

  • Non dispongono di elementi DOM associati.

  • Incapsulano il codice client che deve essere riutilizzato tra le applicazioni.

Comportamenti

  • Derivano dalla classe di base Behavior, che estende la classe di base Component.

  • Estendono il comportamento degli elementi DOM, ad esempio un comportamento di watermarking da associare a una casella di testo esistente.

  • Possono creare elementi dell'interfaccia utente, anche se in genere non modificano il markup dell'elemento DOM associato a cui sono collegati.

  • Se dotati di ID, è possibile accedervi direttamente dall'elemento DOM tramite un attributo personalizzato (expando).

  • Non richiedono un'associazione a un altro oggetto client, ad esempio una classe derivata dalle classi Control o Behavior.

  • Possono fare riferimento a un controllo o a un elemento HTML diverso da un controllo nella relativa proprietà element.

Controlli

  • Derivano dalla classe di base Control, che estende la classe di base Component.

  • Rappresentano un elemento DOM come oggetto client, modificando in genere il comportamento comune dell'elemento DOM originale per fornire nuove funzionalità. Ad esempio, un controllo menu potrebbe leggere gli elementi li da un elemento ul come dati di origine, ma non visualizzare un elenco puntato.

  • È possibile accedervi direttamente dall'elemento DOM tramite il controllo expando.

Prerequisiti

Per eseguire l'esempio del controllo client fornito in questo argomento, è necessario disporre dei seguenti elementi:

Creazione della funzionalità di base per un controllo client ASP.NET AJAX personalizzato

Un controllo client ASP.NET AJAX rappresenta un elemento DOM come oggetto client ed estende una rappresentazione del markup o fornisce funzionalità aggiuntive per l'elemento. Ad esempio, un controllo client potrebbe estendere un elemento HTML per rispondere agli eventi del mouse applicando stili CSS diversi.

Un controllo client incapsula il codice JavaScript da riutilizzare tra le applicazioni. Poiché deriva dalla classe di base Control, il controllo personalizzato eredita automaticamente numerose funzionalità incorporate per la compatibilità tra browser, incluse le seguenti:

  • Possibilità di aggiungere e rimuovere gestori eventi per gli elementi DOM associati al controllo e per i gestori eventi per il controllo stesso.

  • Registrazione automatica del controllo come un oggetto eliminabile che implementa l'interfaccia Sys.IDisposable.

  • Possibilità di generare eventi di notifica quando le proprietà vengono modificate.

  • Possibilità di eseguire l'elaborazione batch delle impostazioni delle proprietà di un controllo. È più efficace in termini di dimensione dello script e tempo di elaborazione rispetto alla gestione di tutta la logica nelle funzioni di accesso get e set per una singola proprietà.

Implementazione di un controllo client

Nella tabella riportata di seguito viene fornito un riepilogo dei passaggi per l'implementazione di un controllo client personalizzato derivato da Control. Alla fine della tabella vengono fornite informazioni più dettagliate su ciascun passaggio.

Passaggio

Riepilogo

Definire una classe del controllo client utilizzando il modello di progettazione del prototipo.

  1. Registrare lo spazio dei nomi per la classe di controllo.

  2. Definire la funzione costruttore del controllo per ricevere un argomento dell'elemento DOM e definire un prototipo.

  3. Registrare la funzione del controllo come classe derivata dalla classe di base Control.

Inizializzare l'istanza Control di base del controllo e passare l'elemento DOM associato come argomento.

  • Nel costruttore del controllo chiamare il metodo Type.initializeBase ereditato e passare l'elemento DOM ricevuto nell'argomento del costruttore alla classe di base.

Esporre una funzione di accesso della proprietà e facoltativamente generare un evento di notifica Sys.Component.propertyChanged.

  • Esporre le proprietà nel prototipo del componente con le funzioni di accesso get e set.

  • Per le proprietà in cui la modifica di una notifica può essere importante, generare un evento di notifica propertyChanged dalla funzione di accesso set della proprietà.

Eseguire l'override del metodo Sys.UI.Control.initialize per inizializzare le proprietà e i listener di eventi.

Se è necessario inizializzare proprietà o listener di eventi per il componente o gli elementi DOM, eseguire l'override del metodo initialize nel prototipo del componente. Nel metodo sottoposto a override, effettuare le operazioni seguenti:

  • Aggiungere i delegati agli eventi DOM dell'oggetto window o di un elemento chiamando il metodo Sys.UI.DomEvent.addHandler.

  • Impostare le proprietà iniziali degli elementi DOM.

  • Impostare le proprietà di accesso facilitato, ad esempio l'indice di tabulazione dell'elemento DOM o l'attributo role del controllo.

  • Chiamare il metodo initialize della classe di base.

Eseguire l'override del metodo Sys.UI.Control.dispose per rilasciare le risorse, ad esempio rimuovendo i gestori eventi degli elementi DOM.

Se è necessario rilasciare risorse prima dell'eliminazione del controllo, eseguire l'override del metodo dispose nel prototipo del componente. Nel metodo sottoposto a override, effettuare le operazioni seguenti:

  • Arrestare i processi che il controllo può accodare internamente e disattivare le funzionalità esposte ai chiamanti.

  • Rimuovere i gestori eventi DOM prima dell'eliminazione del controllo. Cancellando i gestori eventi DOM impostati dal controllo, si rimuovono tutti i riferimenti circolari agli elementi DOM rilasciando la memoria riservata per tali elementi.

  • Chiamare il metodo dispose di base. Tutto il codice presente nel metodo dispose deve poter essere chiamato più volte. Ad esempio, prima di provare a rilasciare una risorsa, verificare che la risorsa non sia già stata rilasciata.

Definizione di una classe di controllo utilizzando il modello di progettazione del prototipo

Una classe client ASP.NET AJAX che include una classe di controllo viene definita in JavaScript utilizzando il modello di progettazione del prototipo. Per informazioni, vedere Creazione di una classe Component del client tramite il modello di prototipo.

Una classe del controllo client deve essere derivata dalla classe di base Control. Registrare una classe client ASP.NET AJAX come classe con l'applicazione client utilizzando il metodo Type.registerClass. Per ulteriori informazioni, vedere Metodo Type.registerClass.

Inizializzazione della classe di base

L'oggetto Control di base viene inizializzato nel costruttore del controllo. Nel costruttore del controllo chiamare il metodo initializeBase ereditato e passare l'elemento DOM ricevuto nell'argomento del costruttore alla classe di base. In genere il metodo initializeBase viene richiamato prima che nel costruttore venga eseguito qualsiasi altro codice. Quando la classe di base Control viene inizializzata, i relativi metodi diventano disponibili per il controllo che viene automaticamente registrato come oggetto eliminabile con l'istanza Sys.Application. Per ulteriori informazioni, vedere Interfaccia Sys.IDisposable.

Nell'esempio seguente viene illustrata una funzione costruttore per un controllo che deriva da Control. Il costruttore del componente chiama il metodo initializeBase ereditato.

Samples.SimpleControl = function(element)
{
    Samples.SimpleControl.initializeBase(this, [element]);
}

Definizione delle proprietà e generazione di notifiche in caso di modifica delle proprietà

Definire le proprietà nella classe del controllo client che gli sviluppatori della pagina possono ottenere e impostare. È inoltre possibile generare eventi di notifica propertyChanged per le proprietà del componente. Gli sviluppatori della pagina che utilizzano il componente possono quindi eseguire l'associazione a questi eventi. Un componente ASP.NET AJAX derivato dalla classe di base Component, Behavior o Control eredita il metodo Sys.Component.raisePropertyChanged che viene chiamato per generare un evento propertyChanged. Per ulteriori informazioni, vedere Definizione di proprietà del componente personalizzato e generazione di eventi PropertyChanged.

Inizializzazione di proprietà e listener di eventi

Se è necessario inizializzare proprietà o listener di eventi per il controllo personalizzato, eseguire l'override del metodo initialize nel prototipo del componente. Un controllo client derivato dalla classe di base Control in genere associa tutti i gestori ai relativi eventi dell'elemento DOM e imposta le proprietà dell'elemento DOM sui valori iniziali. Come ultimo passaggio, chiamare il metodo initialize di base per consentire alla classe di base del componente di completare l'inizializzazione.

Rilascio delle risorse

Se è necessario rilasciare le risorse per il controllo personalizzato prima dell'eliminazione del controllo, eseguire l'override del metodo dispose nel prototipo e rilasciare le risorse nel metodo sottoposto a override. In questo modo le risorse vengono rilasciate immediatamente prima dell'eliminazione del controllo. Le risorse da rilasciare includono i gestori utilizzati per eseguire l'associazione agli eventi DOM. Verificare che siano stati eliminati tutti i possibili riferimenti circolari tra gli elementi DOM e l'oggetto del componente in modo da poter rimuovere l'oggetto dalla memoria. Per ulteriori informazioni, vedere Rilascio delle risorse del componente.

Utilizzo di un controllo in una pagina

Per utilizzare un controllo client personalizzato in una pagina Web ASP.NET, effettuare le seguenti operazioni:

  • Registrare la libreria di script del controllo client nella pagina Web.

  • Creare un'istanza del controllo client.

Nelle sezioni seguenti vengono fornite ulteriori informazioni su questi passaggi.

Registrazione della libreria di script di un controllo nella pagina Web

È possibile registrare gli script necessari per un controllo client nella pagina con un controllo ScriptManager, sia in modo dichiarativo che a livello di codice.

Nell'esempio seguente viene illustrato il markup dichiarativo per un controllo ScriptManager che registra lo script di un controllo.

<form id="form1" >
  <asp:ScriptManager  ID="ScriptManager01">
    <scripts>
      <asp:ScriptReference path="HoverButton.js" />
    </scripts>
  </asp:ScriptManager>
</form>

L'elemento asp:ScriptManager contiene un elemento asp:ScriptReference all'interno di un nodo scripts. L'attributo path dell'elemento asp:ScriptReference fa riferimento al percorso del file HoverButton.js che definisce una classe di controlli. Per ulteriori informazioni, vedere Assegnazione dinamica dei riferimenti a uno script e i cenni preliminari sulla classe ScriptManager.

Nota:

Tutti i file script autonomi che vengono registrati con il controllo ScriptManager devono chiamare il metodo notifyScriptLoaded per notificare all'applicazione il completamento del caricamento dello script. Nella maggior parte dei casi non è consigliabile per gli script incorporati in un assembly chiamare questo metodo. Per ulteriori informazioni, vedere la classe Metodo Sys.Application.notifyScriptLoaded.

Come alternativa alla registrazione dei file script mediante il controllo ScriptManager, è possibile gestire i componenti client utilizzando un controllo server personalizzato che implementi l'interfaccia IScriptControl. Un controllo server personalizzato può registrare automaticamente gli script del componente necessari ed esporre il markup dichiarativo per l'impostazione delle proprietà e delle associazioni eventi del componente. In questo modo viene semplificato l'utilizzo del controllo personalizzato per gli sviluppatori della pagina. Per ulteriori informazioni, vedere i cenni preliminari sulla classe IScriptControl.

Creazione di un'istanza del controllo personalizzato

Creare un'istanza di un controllo client personalizzato chiamando il metodo Sys.Component.create o il collegamento $create durante l'evento Sys.Application.init. Nella tabella riportata di seguito vengono descritti i parametri da passare al metodo $create quando si crea un controllo client.

Parametro

Descrizione

type

Il tipo di componente.

properties

Un oggetto JSON che contiene un valore ID del componente e facoltativamente qualsiasi coppia nome/valore della proprietà iniziale.

events

Un oggetto JSON facoltativo che contiene il nome dell'evento e le coppie di associazione evento/gestore.

references

Un oggetto JSON facoltativo che contiene i riferimenti ai componenti associati, passati come coppie nome/ID componente.

element

L'elemento DOM da associare al controllo.

Nell'esempio seguente viene illustrato come creare un'istanza di un controllo chiamando il metodo $create.

$create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1'));

Per ulteriori informazioni, vedere°Metodo Sys.Component.create e Metodo $create di Sys.Component.

Creazione di un controllo HoverButton personalizzato

In questa sezione verrà creato un controllo client personalizzato semplice denominato HoverButton che estende la classe di base Control e verrà quindi utilizzato in una pagina. Il controllo HoverButton intercetta gli eventi click, focus e mouseover di un elemento HTML button associato. Vengono inoltre forniti i controlli con eventi associabili tramite il metodo $create. Un sviluppatore della pagina che utilizza il controllo HoverButton può eseguire l'associazione all'evento hover del controllo.

Per creare il codice per il controllo HoverButton personalizzato

  1. Nella directory radice di un sito Web ASP.NET con supporto AJAX, creare un file denominato HoverButton.js.

  2. Aggiungere al file il codice riportato di seguito:

    Type.registerNamespace("Demo");
    
    // Constructor
    Demo.HoverButton = function(element) {
    
        Demo.HoverButton.initializeBase(this, [element]);
    
        this._clickDelegate = null;
        this._hoverDelegate = null;
        this._unhoverDelegate = null;
    }
    Demo.HoverButton.prototype = {
    
        // text property accessors.
        get_text: function() {
            return this.get_element().innerHTML;
        },
        set_text: function(value) {
            this.get_element().innerHTML = value;
        },
    
        // Bind and unbind to click event.
        add_click: function(handler) {
            this.get_events().addHandler('click', handler);
        },
        remove_click: function(handler) {
            this.get_events().removeHandler('click', handler);
        },
    
        // Bind and unbind to hover event.
        add_hover: function(handler) {
            this.get_events().addHandler('hover', handler);
        },
        remove_hover: function(handler) {
            this.get_events().removeHandler('hover', handler);
        },
    
        // Bind and unbind to unhover event.
        add_unhover: function(handler) {
            this.get_events().addHandler('unhover', handler);
        },
        remove_unhover: function(handler) {
            this.get_events().removeHandler('unhover', handler);
        },
    
        // Release resources before control is disposed.
        dispose: function() {
    
            var element = this.get_element();
    
            if (this._clickDelegate) {
                Sys.UI.DomEvent.removeHandler(element, 'click', this._clickDelegate);
                delete this._clickDelegate;
            }
    
            if (this._hoverDelegate) {
                Sys.UI.DomEvent.removeHandler(element, 'focus', this._hoverDelegate);
                Sys.UI.DomEvent.removeHandler(element, 'mouseover', this._hoverDelegate);
                delete this._hoverDelegate;
            }
    
            if (this._unhoverDelegate) {
                Sys.UI.DomEvent.removeHandler(element, 'blur', this._unhoverDelegate);
                Sys.UI.DomEvent.removeHandler(element, 'mouseout', this._unhoverDelegate);
                delete this._unhoverDelegate;
            }
            Demo.HoverButton.callBaseMethod(this, 'dispose');
        },
    
        initialize: function() {
    
            var element = this.get_element();
    
            if (!element.tabIndex) element.tabIndex = 0;
    
            if (this._clickDelegate === null) {
                this._clickDelegate = Function.createDelegate(this, this._clickHandler);
            }
            Sys.UI.DomEvent.addHandler(element, 'click', this._clickDelegate);
    
            if (this._hoverDelegate === null) {
                this._hoverDelegate = Function.createDelegate(this, this._hoverHandler);
            }
            Sys.UI.DomEvent.addHandler(element, 'mouseover', this._hoverDelegate);
            Sys.UI.DomEvent.addHandler(element, 'focus', this._hoverDelegate);
    
            if (this._unhoverDelegate === null) {
                this._unhoverDelegate = Function.createDelegate(this, this._unhoverHandler);
            }
            Sys.UI.DomEvent.addHandler(element, 'mouseout', this._unhoverDelegate);
            Sys.UI.DomEvent.addHandler(element, 'blur', this._unhoverDelegate);
    
            Demo.HoverButton.callBaseMethod(this, 'initialize');
    
        },
        _clickHandler: function(event) {
            var h = this.get_events().getHandler('click');
            if (h) h(this, Sys.EventArgs.Empty);
        },
        _hoverHandler: function(event) {
            var h = this.get_events().getHandler('hover');
            if (h) h(this, Sys.EventArgs.Empty);
        },
        _unhoverHandler: function(event) {
            var h = this.get_events().getHandler('unhover');
            if (h) h(this, Sys.EventArgs.Empty);
        }
    }
    Demo.HoverButton.registerClass('Demo.HoverButton', Sys.UI.Control);
    
    // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
    // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager 
    // that this is the end of the script.
    if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
    
    

Illustrazione del codice

Il codice registra lo spazio dei nomi Demo chiamando il metodo Type.registerNamespace. Il costruttore richiama il metodo initializeBase ereditato in modo da rendere disponibili i metodi della classe di base Control. La classe di base inizializzata registra a sua volta l'istanza Demo.HoverButton con l'applicazione client come oggetto eliminabile.

Nel prototipo il codice dichiara gli eventi pubblici clickhover e unhover. Lo sviluppatore della pagina può aggiungere e rimuovere i gestori che restano in ascolto di tali eventi. Questi metodi a loro volta aggiungono o rimuovono il gestore specificato tramite l'insieme di gestori eventi del controllo. Aggiungere e rimuovere i gestori nella classe di controllo tramite l'oggetto Sys.EventHandlerList del controllo. L'oggetto EventHandlerList contiene un insieme di gestori eventi del controllo tramite la proprietà Sys.Component.events ereditata. Nell'esempio il codice richiama i metodi Sys.EventHandlerList.addHandler e Sys.EventHandlerList.removeHandler dell'oggetto EventHandlerList restituito in modo da aggiungere o rimuovere i gestori.

La classe HoverButton esegue l'override del metodo dispose di base per eliminare in modo sicuro tutte le risorse del controllo, ad esempio i gestori per gli eventi DOM, prima dell'eliminazione del controllo. Infine, il codice chiama il metodo dispose di base per consentire all'applicazione di rilasciare il controllo.

Utilizzo del controllo HoverButton in una pagina Web

In questa sezione viene illustrato come creare un'istanza del controllo utilizzando uno script client in una pagina Web.

Per creare una pagina per utilizzare il controllo HoverButton

  1. Nella directory radice dell'applicazione in cui si trova il file HoverButton.js, creare un file denominato DemoHoverButton.aspx.

  2. Aggiungere al file il codice e il markup riportati di seguito:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" >
    
        <style type="text/css">
            button {border: solid 1px black}
            #HoverLabel {color: blue}
        </style>
        <title>Control Demo</title>
    </head>
    <body>
        <form id="form1" >
            <div id="ResultDisplay"></div>
    
                <asp:ScriptManager  ID="ScriptManager01">
                    <scripts>
                       <asp:ScriptReference Path="HoverButton.js" />
                    </scripts>
                </asp:ScriptManager>
    
                <script type="text/javascript">
                    var app = Sys.Application;
                    app.add_init(applicationInitHandler);
    
                    function applicationInitHandler(sender, args) {
                        $create(Demo.HoverButton, {text: 'A HoverButton Control',element: {style: {fontWeight: "bold", borderWidth: "2px"}}}, {click: start, hover: doSomethingOnHover, unhover: doSomethingOnUnHover},null, $get('Button1'));
                    }
    
                    function doSomethingOnHover(sender, args) {
                        hoverMessage = "The mouse is over the button."
                        $get('HoverLabel').innerHTML = hoverMessage;
                    }
    
                    function doSomethingOnUnHover(sender, args) {
                       $get('HoverLabel').innerHTML = "";
                    }
    
                    function start(sender, args) {
                       alert("The start function handled the HoverButton click event.");
                    }
                </script>
    
                <button type="button" id="Button1"></button>&nbsp;
            <div id="HoverLabel"></div>
        </form>
    
    </body>
    </html>
    

Illustrazione del codice

Il file DemoHoverButton.aspx è una pagina Web ASP.NET che ospita il controllo personalizzato. Nella pagina le funzioni associate al controllo personalizzato vengono definite nell'elemento script. Nel gestore eventi Sys.Application.init viene creata un'istanza del controllo HoverButton nello script client chiamando il metodo $create. Il codice passa al metodo $create i seguenti argomenti:

  • L'argomento type contiene la classe Demo.HoverButton creata precedentemente.

  • L'argomento properties contiene un oggetto JSON contenente il valore ID del controllo necessario, seguito dalle coppie nome/valore della proprietà che specificano i nomi delle proprietà con i valori iniziali.

  • L'argomento events contiene un oggetto contenente le coppie nome evento/gestore.

Nel controllo ScriptManager l'attributo path del nodo asp:ScriptReference fa riferimento al percorso del file HoverButton.js che definisce la classe del controllo Demo.HoverButton.

Impostazione di gestori eventi degli elementi DOM e di gestori eventi dei componenti

La funzionalità AJAX in ASP.NET include le classi che forniscono la gestione degli eventi standardizzata per i componenti e gli elementi DOM. Gestire gli eventi del controllo utilizzando i membri della classe Sys.EventHandlerList, ad esempio addHandler e removeHandler. Per ulteriori informazioni, vedere i cenni preliminari sulla classe Sys.EventHandlerList.

Gestire i gestori eventi per gli elementi DOM o per gli eventi dell'oggetto window utilizzando i metodi statici della classe Sys.UI.DomEvent, addHandler o removeHandler. Per ulteriori informazioni, vedere i cenni preliminari sulla classe Sys.UI.DomEvent.

Accesso alle proprietà dell'elemento DOM

La classe Sys.UI.DomElement contiene i membri che consentono di aggiungere, rimuovere e attivare o disattivare le associazioni della classe CSS per i controlli client e gli elementi. Questi membri forniscono anche l'accesso standardizzato alle proprietà degli elementi DOM. Per ulteriori informazioni, vedere Classe Sys.UI.DomElement.

Vedere anche

Attività

Creazione di componenti client non visivi personalizzati

Assegnazione dinamica dei riferimenti a uno script

Concetti

Utilizzo del controllo UpdatePanel ASP.NET con più controlli con associazione a dati

Utilizzo di eventi PageRequestManager

Riferimenti

Classe Sys.Component

ScriptManager