Compartir a través de


Crear controles de cliente de AJAX personalizados

Actualización: noviembre 2007

Esta introducción muestra cómo crear un control de cliente de AJAX personalizado en ASP.NET y utilizarlo en una página. En esta introducción aprenderá a hacer lo siguiente:

  • Utilizar el modelo de diseño de prototipos de ECMAScript (JavaScript) para definir una clase de control.

  • Registrar un control como una clase que deriva de la clase base Sys.UI.Control.

  • Inicializar la clase base Control e invocar sus métodos.

  • Crear eventos personalizados a los que un desarrollador de páginas puede enlazar y administrar.

  • Utilizar el control de cliente en una página y enlazar a los eventos de control.

En la introducción se ofrece un ejemplo de un control de cliente completo que crea un botón con comportamiento de desplazamiento.

Esta introducción se centra en los controles de cliente. Existen tres tipos de objetos de componente cliente de AJAX en ASP.NET:

  • Componentes no visuales que derivan de la clase base Sys.Component y que no tienen ninguna representación de interfaz de usuario.

  • Comportamientos que derivan de Sys.UI.Behavior.

  • Controles que derivan de Control.

La tabla siguiente resume las diferencias entre los componentes, comportamientos y controles.

Tipos de objeto de componente cliente

Resumen

Componentes

  • Derivan de la clase base Component.

  • Normalmente, no tienen ninguna representación de interfaz de usuario, como un componente de temporizador que provoca eventos a intervalos pero no está visible en la página.

  • No tienen ningún elemento DOM asociado.

  • Encapsulan el código de cliente diseñado para reutilizarse en varias aplicaciones.

Comportamientos

  • Derivan de la clase base Behavior, que extiende la clase base Component.

  • Extienden el comportamiento de los elementos DOM, como el comportamiento de impresión de marcas de agua que puede asociarse a un cuadro de texto existente.

  • Pueden crear elementos de la interfaz de usuario, aunque normalmente no modifican el marcado del elemento DOM al que están asociados.

  • Si se les asigna un identificador, se puede tener acceso directamente desde el elemento DOM a través de un atributo personalizado (expando).

  • No requieren una asociación con otro objeto de cliente, como una clase derivada de las clases Control o Behavior.

  • Pueden hacer referencia a un control o a un elemento HTML que no sea un control en su propiedad element.

Controles

  • Derivan de la clase base Control, que extiende la clase base Component.

  • Representan un elemento DOM como un objeto de cliente, cambiando normalmente el comportamiento habitual del elemento DOM original para proporcionar la nueva funcionalidad. Por ejemplo, un control de menú podría leer los elementos li de un elemento ul como sus datos de origen, pero no mostrar una lista con viñetas.

  • Se obtiene acceso directamente desde el elemento DOM a través del expando del control.

Requisitos previos

Para ejecutar el ejemplo de control de cliente proporcionado en este tema, necesitará:

Crear la funcionalidad básica de control de cliente de AJAX personalizado en ASP.NET

Un control de cliente de AJAX de ASP.NET representa un elemento DOM como un objeto de cliente y extiende una representación de marcado o proporciona funcionalidad adicional para el elemento. Por ejemplo, un control de cliente podría extender un elemento HTML para reaccionar a los eventos del mouse aplicando estilos CSS diferentes.

Un control de cliente encapsula el código JavaScript diseñado para ser reutilizado en varias aplicaciones. Al derivar de la clase base Control, el control personalizado hereda automáticamente muchas de las características integradas entre exploradores, incluidas las siguientes:

  • Capacidad para agregar y quitar controladores de eventos para los elementos DOM asociados al control y para los controladores de eventos del propio control.

  • Registro automático del control como un objeto descartable que implementa la interfaz Sys.IDisposable.

  • Capacidad para provocar eventos de notificación cuando se cambian las propiedades.

  • Capacidad para realizar procesamiento por lotes de los valores de propiedad del control. Esto es más eficaz en cuanto a tamaño del script y tiempo de proceso que administrar toda la lógica en los descriptores de acceso get y set de cada propiedad.

Implementar un control de cliente

En la tabla siguiente se resumen los pasos para implementar un control de cliente personalizado derivado de Control. A continuación de la tabla encontrará información más detallada sobre cada paso.

Paso

Resumen

Defina una clase de control de cliente utilizando el modelo de diseño de prototipos.

  1. Registre el espacio de nombres para su clase de control.

  2. Defina la función de constructor del control para recibir un argumento de elemento DOM y defina un prototipo.

  3. Registre la función de control como una clase que se deriva de la clase base Control.

Inicialice la instancia base de Control del control y pase el elemento DOM asociado como un argumento.

  • En el constructor del control, llame a su método Type.initializeBase heredado y pase el elemento DOM recibido en el argumento del constructor a la base.

Exponga los descriptores de acceso de propiedad y, opcionalmente, provoque un evento de notificación Sys.Component.propertyChanged.

  • Exponga las propiedades del prototipo del componente con descriptores de acceso get y set.

  • En el caso de las propiedades para las que la notificación de cambios podría ser importante, provoque un evento de notificación propertyChanged desde el descriptor de acceso set de la propiedad.

Invalide el método Sys.UI.Control.initialize para inicializar las propiedades y los agentes de escucha de eventos.

Si hay propiedades o agentes de escucha de eventos para que se inicialice el componente o los elementos DOM, invalide el método initialize en el prototipo del componente. En el método invalidado, haga lo siguiente:

  • Agregue delegados a los eventos DOM del objeto window o de un elemento mediante una llamada al método Sys.UI.DomEvent.addHandler.

  • Establezca las propiedades iniciales de los elementos DOM.

  • Establezca las propiedades de accesibilidad, como el índice de tabulación del elemento DOM o el atributo role del control.

  • Llame al método initialize de la clase base.

Invalide el método Sys.UI.Control.dispose para liberar recursos, por ejemplo, quitar los controladores de eventos DOM.

Si hay que liberar recursos antes de eliminar el control, invalide el método dispose en el prototipo del componente. En el método invalidado, haga lo siguiente:

  • Detenga los procesos que el control podría poner en la cola internamente y deshabilite cualquier funcionalidad expuesta a los llamadores.

  • Quite los controladores de eventos DOM antes de eliminar el control. Al quitar los controladores de elementos DOM establecidos por su control, se quita cualquier referencia circular a esos elementos DOM y se libera la memoria reservada para esos elementos.

  • Llame al método base dispose. Todo el código del método dispose se debe poder invocar varias veces. Por ejemplo, antes de intentar liberar un recurso, compruebe que el recurso aún no ha sido liberado.

Definir una clase de control mediante el modelo de diseño de prototipos

Una clase de cliente AJAX de ASP.NET, que incluye una clase de control, se define en JavaScript utilizando el modelo de diseño de prototipos. Para obtener información detallada, vea Crear una clase de componente de cliente utilizando el modelo de prototipo.

Una clase de control de cliente debe derivarse de la clase base Control. Para registrar una clase de cliente AJAX de ASP.NET como una clase en la aplicación cliente, utilice el método Type.registerClass. Para obtener más información, vea Type.registerClass (Método).

Inicializar la clase base

El objeto Control base se inicializa en el constructor del control. En el constructor del control, invoque el método initializeBase heredado y pase el elemento DOM recibido en el argumento de constructor a la clase base. Normalmente, el método initializeBase se invoca antes de que se ejecute cualquier otro código en el constructor. Cuando se inicializa la clase base Control, sus métodos están disponibles para el control y registra automáticamente el control como un objeto descartable en la instancia de Sys.Application. Para obtener más información, vea Sys.IDisposable (Interfaz).

En el ejemplo siguiente se muestra una función de constructor para un control que deriva de Control. El constructor del componente llama al método initializeBase heredado.

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

Definir propiedades y emitir notificaciones de cambios en las propiedades

En la clase de control de cliente se definen propiedades que los desarrolladores de páginas pueden obtener y establecer. También puede provocar eventos de notificación propertyChanged para las propiedades del componente. Los desarrolladores de páginas que utilicen su componente pueden enlazar a estos eventos. Un componente AJAX de ASP.NET derivado de la clase base Component, Behavior o Control, hereda el método Sys.Component.raisePropertyChanged, al que se llama para provocar un evento propertyChanged. Para obtener más información, vea Definir propiedades de componentes personalizados y provocar eventos PropertyChanged.

Inicializar propiedades y agentes de escucha de eventos

Si el control personalizado debe inicializar propiedades o agentes de escucha de eventos, invalide el método initialize en el prototipo del componente. Normalmente, un control de cliente derivado de la clase base Control enlaza los controladores a sus eventos de elemento DOM y establece las propiedades de los elementos DOM en sus valores iniciales. Como paso final, se llama al método initialize base para que la clase base del componente pueda completar la inicialización.

Liberar recursos

Si el control personalizado debe liberar recursos antes de eliminar el control, invalide el método dispose y libere los recursos de método invalidado. De esta manera, se asegura de que los recursos se liberan inmediatamente antes de eliminar el control. Entre los recursos para liberar se incluyen los controladores utilizados para enlazar a eventos DOM. Compruebe que se han quitado las posibles referencias circulares entre los elementos DOM y el objeto de componente para asegurarse de que el objeto se puede quitar de la memoria. Para obtener más información, vea Liberar recursos de componente.

Utilizar un control en una página

Para utilizar un control de cliente personalizado en una página web ASP.NET, haga lo siguiente:

  • Registre la biblioteca de scripts del control de cliente en la página web.

  • Cree una instancia del control de cliente.

Las secciones siguientes proporcionan detalles acerca de estos pasos.

Registrar una biblioteca de scripts del control en la página web

Puede registrar los scripts necesarios para un control de cliente en la página con un control ScriptManager, mediante declaración o mediante programación.

El ejemplo siguiente muestra el marcado declarativo para un control ScriptManager que registra un script de control.

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

El elemento asp:ScriptManager contiene un elemento asp:ScriptReference dentro de un nodo scripts. El atributo path del elemento asp:ScriptReference hace referencia a la ruta de acceso del archivo HoverButton.js que define una clase de control. Para obtener más información, vea Asignar referencias de script de forma dinámica y la información general de la clase ScriptManager.

Nota:

Todos los archivos de script independientes que se registrarán con el control ScriptManager deben llamar al método notifyScriptLoaded para notificar a la aplicación que el script ha terminado de cargarse. En la mayoría de los casos, los scripts incrustados en un ensamblado no deben llamar a este método. Para obtener más información, vea Sys.Application.notifyScriptLoaded (Método).

Como alternativa al registro de archivos de script mediante el control ScriptManager, puede administrar los componentes de cliente utilizando un control de servidor personalizado que implemente la interfaz IScriptControl. Un control de servidor personalizado puede registrar automáticamente los scripts de componente necesarios y exponer el marcado declarativo para establecer las propiedades del componente y los enlaces de evento. De esta manera resulta más sencillo que un desarrollador de páginas utilice su control personalizado. Para obtener más información, vea la información general de la clase IScriptControl.

Crear una instancia de un control personalizado

Las instancias de un control de cliente personalizado se crean mediante llamadas al método Sys.Component.create o al método abreviado $create durante el evento Sys.Application.init. En la tabla siguiente se describen los parámetros que se pasan al método $create al crear un control de cliente.

Parámetro

Descripción

type

Tipo de componente.

properties

Objeto JSON que contiene un valor de identificador de componente y, opcionalmente, pares de nombres-valores iniciales de propiedad.

events

Objeto JSON opcional que contiene nombres de eventos y pares de enlaces evento-controlador.

references

Objeto JSON opcional que contiene referencias a los componentes asociados, pasadas como pares de nombre-identificador de componente.

element

Elemento DOM que se va a asociar al control.

En el ejemplo siguiente se muestra cómo crear instancias de un control mediante una llamada al método $create.

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

Para obtener más información, vea Sys.Component.create (Método) y Sys.Component $create (Método).

Crear el control HoverButton personalizado

En esta sección se creará un control de cliente simple personalizado denominado HoverButton que extiende la clase base Control y, a continuación, se utilizará el control en una página. El control HoverButton intercepta los eventos click, focus y mouseover de un elemento HTML button asociado. También proporciona a los controles los eventos a los que se puede enlazar a través del método $create. Los desarrolladores de páginas que utilizan el control HoverButton pueden enlazar al evento hover del control.

Para crear el código del control HoverButton

  1. En el directorio raíz de un sitio web ASP.NET habilitado para AJAX, cree un archivo denominado HoverButton.js.

  2. Agregue el código siguiente al archivo:

    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();
    
    

Descripción del código

El código registra el espacio de nombres Demo mediante una llamada al método Type.registerNamespace. El constructor invoca el método initializeBase heredado para que los métodos de la clase base Control estén disponibles. A su vez, la clase base inicializada registra la instancia de Demo.HoverButton en la aplicación cliente como un objeto descartable.

En el prototipo, el código declara los eventos públicos click, hover y unhover. El desarrollador de páginas puede agregar y quitar los controladores que realizan escuchas para esos eventos. A su vez, estos métodos agregan o quitan el controlador especificado mediante la colección de controladores de eventos del control. Se puede agregar y quitar los controladores de su clase de control mediante el objeto Sys.EventHandlerList del control. El objeto EventHandlerList contiene una colección de los controladores de eventos del control mediante la propiedad heredada Sys.Component.events. En el ejemplo, el código invoca los métodos Sys.EventHandlerList.addHandler y Sys.EventHandlerList.removeHandler del objeto EventHandlerList devuelto para agregar o quitar los controladores.

La clase HoverButton invalida el método base dispose para eliminar sin riesgos los recursos del control (como los controladores de los eventos DOM) antes de eliminar el control. Finalmente, el código llama al método dispose base para que la aplicación pueda liberar el control.

Utilizar el control HoverButton en una página web

En esta sección, aprenderá crear una instancia de control mediante un script de cliente en una página web.

Para crear una página para utilizar el control HoverButton

  1. En el directorio raíz de la aplicación donde se encuentra el archivo HoverButton.js, cree un archivo denominado DemoHoverButton.aspx.

  2. Agregue el siguiente marcado y código al archivo:

    <!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>
    

Descripción del código

El archivo DemoHoverButton.aspx es una página web ASP.NET que hospeda el control personalizado. En la página, las funciones enlazadas al control personalizado se definen en el elemento script. En el controlador de eventos Sys.Application.init, se crean las instancias del control HoverButton en el script de cliente mediante llamadas al método $create. El código pasa los siguientes argumentos al método $create:

  • El argumento tipo contiene la clase Demo.HoverButton creada anteriormente.

  • El argumento properties contiene un objeto JSON que contiene el valor de identificador de control necesario, seguido por los pares nombre-valor de propiedad que especifican los nombres de propiedad y sus valores iniciales.

  • El argumento events contiene un objeto que contiene los nombres de evento emparejados con sus controladores.

En el control ScriptManager, el atributo path del nodo asp:ScriptReference hace referencia a la ruta de acceso del archivo HoverButton.js file que define la clase de control Demo.HoverButton.

Establecer controladores de eventos de elementos DOM y controladores de eventos de componentes

La funcionalidad AJAX de ASP.NET incluye clases que permiten una administración normalizada de los eventos de componentes y de elementos DOM. Los eventos del control se administran utilizando miembros de la clase Sys.EventHandlerList, como addHandler y removeHandler. Para obtener más información, vea la introducción a la clase Sys.EventHandlerList.

Los controladores de eventos de elementos DOM o de objetos window se administran mediante los métodos estáticos de la clase Sys.UI.DomEvent, addHandler o removeHandler. Para obtener más información, vea la introducción a la clase Sys.UI.DomEvent.

Obtener acceso a las propiedades de elementos DOM

La clase Sys.UI.DomElement contiene miembros que permiten agregar, quitar y alternar las asociaciones de las clases CSS para los controles y elementos de cliente. Estos miembros también proporcionan acceso normalizado a las propiedades de los elementos DOM. Para obtener más información, vea Sys.UI.DomElement (Clase).

Vea también

Tareas

Crear componentes de cliente no visuales personalizados

Asignar referencias de script de forma dinámica

Conceptos

Usar el control UpdatePanel de ASP.NET con controles enlazados a datos

Trabajar con eventos de PageRequestManager

Referencia

Sys.Component (Clase)

ScriptManager