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 |
|
Comportamientos |
|
Controles |
|
Requisitos previos
Para ejecutar el ejemplo de control de cliente proporcionado en este tema, necesitará:
- Un sitio web ASP.NET habilitado para AJAX. Si tiene un sitio como este ya configurado, puede utilizarlo para este ejemplo. Para obtener más información sobre cómo crear un directorio o sitio virtual, vea Cómo: Crear y configurar directorios virtuales en IIS 5.0 y 6.0.
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. |
|
Inicialice la instancia base de Control del control y pase el elemento DOM asociado como un argumento. |
|
Exponga los descriptores de acceso de propiedad y, opcionalmente, provoque un evento de notificación Sys.Component.propertyChanged. |
|
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:
|
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:
|
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
En el directorio raíz de un sitio web ASP.NET habilitado para AJAX, cree un archivo denominado HoverButton.js.
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
En el directorio raíz de la aplicación donde se encuentra el archivo HoverButton.js, cree un archivo denominado DemoHoverButton.aspx.
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> <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