DirectMethods y control GridPanel
Esta parte de la serie sobre Ext.Net va a ser extensa debido a que veremos varios temas: como manejar un evento del lado del servidor con DirectMethods tal como lo he mencionado anteriormente como utilizar el control GridPanel el cual es un grillado que nos permite presentar información, y algunas características especiales de este control como son las barras de herramientas y los renderizadores.
DirectMethods es otra forma de manejar eventos del lado del servidor, para crear un direct method se debe marcar un método con el atributo [DirectMethod], cuando se produce la renderización de la pagina y un método esta marcado con este atributo lo que hace ExtNet es generar código javascript que nos permita invocarlo directamente, por ejemplo:
[DirectMethod] public void Buscar(string nombres, string edad)
se convierte en
Ext.net.DirectMethods.Buscar(nombres,edad)
Así lo podemos invocar directamente desde javascript, en este ejemplo tenemos un control GridPanel que nos presenta una lista de empleados y una sección en donde con criterios de búsqueda: nombres y edad, al presionar el botón buscar se invoca el Direct Method, noten el uso de #{<nombreComponente>}, esto nos permite obtener una referencia al elemento dentro de la pagina por su nombre, aquí lo utilizamos para obtener el valor del campo nombre y edad.
<ext:Button ID="botonBuscar" runat="server" Text="Buscar" Icon="Zoom">
<Listeners>
<Click Fn="buscar" />
</Listeners>
</ext:Button>
var buscar = function () {
var nombres = #{nombreCompletoBusqueda}.getValue();
var edad = #{edadBusqueda}.getValue();
Ext.net.DirectMethods.Buscar(nombres, edad);
}
Cuando presionamos el botón de búsqueda se produce el llamado al método Buscar definido en el servidor, si revisamos los datos de la petición notaran que los valores viajan como extraParams igual que un DirectEvent pero a diferencia de éste no es necesario obtenerlos accediendo a una colección sino que ya son enlazados según los parámetros definidos.
La respuesta es un script en formato JSON que llama al método del store (lo veremos más adelante por ahora piensa en el store como la fuente de datos del GridPanel): callbackRefreshHandler, recordemos que al ser una llamada AJAX se produce un callback cuando se termina de procesar esta petición, la información que contiene la respuesta se divide en dos partes:
- Información de la peticion (serviceResponse, success, etc)
- El contenido de la lista de los empleados, en la propiedad Data
El control llamado store sirve como la fuente de datos para otros controles, por ejemplo: GridPanel, ComboBox, o sea todos aquellos controles orientados a presentar información, este control se asocia directamente al Grid a través de la propiedad Store, posee un Reader definido en este este ejemplo como un JsonReader con una colección de campos,la asignación de IDProperty al campo ID determina la unicidad de los registros en el store, recuerdan que se dijo anteriomente que la respuesta de presionar el botón Buscar estaba en formato JSON, el JsonReader puede interpretar esta respuesta.
<Store>
<ext:Store ID="storeEmpleados" runat="server">
<Reader>
<ext:JsonReader IDProperty="ID">
<Fields>
<ext:RecordField Name="NombreCompleto"></ext:RecordField>
<ext:RecordField Name="Edad"></ext:RecordField>
<ext:RecordField Name="Cargo"></ext:RecordField>
<ext:RecordField Name="FechaContrato"></ext:RecordField>
<ext:RecordField Name="Activo"></ext:RecordField>
</Fields>
</ext:JsonReader>
</Reader>
</ext:Store>
</Store>
GridPanel nos permite tener tres barras una superior (TopBar), otra inferior (BottomBar) y una al pie del control (FooterBar), por defecto tienen determinado un layout tipo Form por esta razón podemos colocar directamente controles tipo TextField, ComboBox y sus valores para FieldLabel se presentaran automáticamente. En este caso se coloco los controles de búsqueda en el TopBar:
<TopBar>
<ext:Toolbar runat="server">
<Items>
<ext:TextField ID="nombreCompletoBusqueda" runat="server" FieldLabel="Nombres" Width="400"></ext:TextField>
<ext:NumberField ID="edadBusqueda" runat="server" FieldLabel="Edad"></ext:NumberField>
<ext:Button ID="botonBuscar" runat="server" Text="Buscar" Icon="Zoom">
<Listeners>
<Click Fn="buscar" />
</Listeners>
</ext:Button>
</Items>
</ext:Toolbar>
</TopBar>
El store corresponde a la parte de datos, ahora veremos como definir la parte de presentación para el GridPanel, esto es determinado por las propiedades ColumnModel y SelectionModel la primera va a definir una colección de columnas, mientras que la segunda establece la forma en que una fila en el Grid puede ser seleccionada.
Así en la colección Columns para ColumnModel tenemos varias columnas con la siguiente estructura
<ext:Column ColumnID="NombreCompleto" DataIndex="NombreCompleto" Header="Nombres"></ext:Column>
ColumnID, en este caso es utilizado para establecer que la columna de Nombres sea principal en el Grid, a través de la propiedad AutoExpandColumn Nombres se expandirá automáticamente hasta completar el ancho del Grid.
DataIndex, es el nombre de un RecordField en el Store, permite enlazar el Store al modelo de columnas y establecer cual es la propiedad que se debe presentar en esta columna, y
Header, que es el texto del encabezado de la columna.
SelectionModel simplemente determina que se puede seleccionar una fila completa y solo una a la vez.
<SelectionModel>
<ext:RowSelectionModel SingleSelect="true" />
</SelectionModel>
Las columnas Edad y Activo tienen un Render o renderizador, estos nos permiten mejorar la experiencia del usuario cuando se presenta la información, por ejemplo, edad es un valor entero, con edadRenderer se crea una cadena con el valor de la columna y la palabra “años”, la columna Activo es un valor booleano, en este caso se utiliza dos iconos para indicar si el empleado si esta activo o no, en lugar de presentar los valores true o false.
var edadRenderer = function (value) {
return value + ' ' + 'años';
}
var activoRenderer = function (value) {
if (value)
return "<img src='drop-yes.gif' alt='Activo' />";
else
return "<img src='drop-no.gif' alt='Inactivo' />";
};
Cada render es una función que recibe implícitamente un parámetro llamado value con el valor de cada uno de los registros, el valor que se devuelve, en este caso una cadena, es lo que se presenta en la celda.
Sin renderizadores tendríamos:
y aplicando los renderizadores, noten como se cambian los valores de las celdas:
Hasta ahora hemos visto la parte visual, del lado del servidor tenemos una clase Empleado como contenedor de los datos de este ejemplo y un repositorio para simular el acceso a una base de datos, algo importante que se ejecuta en el Load de la página es esto:
//X es lo mismo que ExtNet
//if(ExtNet.IsAjaxRequest)
if (!X.IsAjaxRequest){}
X es un alias para la clase ExtNet, contiene varios métodos y propiedades de utilidad, la propiedad IsAjaxRequest que devuelve un valor verdadero si la petición es del tipo AJAX, cuando se carga la pagina por primera vez esta petición no es del tipo AJAX por lo cual llenamos (bind) el store con los datos de todos los empleados.
Hemos cubierto la forma en que se escribe un DirectMethod, un control GridPanel para presentar información de empleados y como utilizar renderizadores para mejorar la experiencia del usuario, en el siguiente post que será el ultimo de esta serie introductoria veremos como paginar un Grid o cualquier otro control que soporte paginación.
Hasta la proxima!
Links útiles:
edison, gracias por responder mi consulta anterior, pero creo me expresé mal, cuando me referia a gráficos era a charts, es decir mostrar por ejemplo un chart de barras que represente los datos de una grilla
saludos
alejandra
Actualmente la versión de Ext.Net no contiene la implementación para ese tipo de gráficos, ya que está soportando la versión 3.3.0 de ExtJS, no es hasta la versión de ExtJS 4.0 en donde se incluyen este tipos de controles, puedes revisar en http://www.sencha.com/products/extjs/examples/#sample-3. Sin embargo se puede utilizar alguna otra librería que contenga este tipo de graficos, ya que pueden coexistir normalmente con Ext.Net