• No se han encontrado resultados

4 lA clASE dATAviEW

en estos momentos ya hemos decidido cómo vamos a visualizar la información, pero para que sirva de algo tenemos que indicar a aJaX cómo queremos utilizarla. La clase Sys.UI.DataView definida en la infraestructura de cliente de asP.NeT aJaX es la clave para activar las plantillas.

Un DataView es un control de lado de cliente que nos permite relacionar un ori- gen de datos y una plantilla para generar, de manera automática, el hTML necesario para visualizar la información.

Los datos manejados por esta clase son muy variados: pueden ser matrices de objetos creadas en la propia página, datos resultantes de llamar a un servicio Web en el servidor o clases especializadas que ofrece aJaX para conectarse automática- mente a estos servicios Web (y que luego estudiaremos).

cuando se le asigna una matriz o colección de objetos, el DataView actúa como un repetidor de la plantilla, generando una instancia por cada elemento de la matriz. se asemejaría a un control ListView o un Repeater de asP.NeT pero en el lado cliente. si por el contrario se le asigna un único objeto la plantilla sólo se instancia una vez y el control actúa como un visualizador de entidades (se parecería a un control de servidor DetailsView).

existen tres maneras fundamentales de asociar datos a este control:

asociarle directamente una matriz de objetos o un objeto en su propiedad 1.

data. si, por ejemplo, tenemos una matriz de objetos ya definida en la propia página pues no se obtiene dinámicamente de un servicio externo. es la forma menos habitual.

Indicarle la dirección relativa de un servicio Web que proporciona los datos, 2.

para lo cual la propiedad adecuada es dataProvider. además en este caso es necesario indicarle mediante otra propiedad llamada fetchMethod el nombre de la operación del servicio que debe llamar para recuperar los datos. Utilizar un objeto especializado para comunicarse con el servidor y usar éste 3.

como proveedor de datos para el DataView. se asigna el objeto especializado directamente a la propiedad dataProvider. estudiaremos estos objetos en un apartado posterior.

existen dos maneras de instanciar el control DataView y asignarle los datos y la plantilla: por código y de manera declarativa.

Para instanciarlo mediante código lo más sencillo es utilizar el método especial de asP.NeT aJaX llamado $create. el mejor sitio suele ser el evento init de la clase

Application, y que se ejecuta al cargar la página. La sintaxis sería la siguiente:

Sys.Application.add_init(function() {

$create(

{ data: “Servicios/NorthwindService.svc”, fetchOperation: “GetAllProducts” }, null, null, $get(“Productos-template”) ); });

La creación toma como parámetros el tipo de clase a crear, las propiedades del objeto que queramos establecer durante la creación, los manejadores de eventos que queramos asignar (en este caso ninguno, por eso se pasa un nulo), las referencias a otros componentes que se necesiten (ninguna en el caso de este control), y finalmente la plantilla a la que queremos asociar el DataView. ¡Buff!. Parece complicado pero no lo es tanto una vez que te acostumbras.

De todas maneras lo más habitual es utilizar el control DataView de manera declarativa, es decir, sin necesidad de escribir código. esto es mucho más fácil y rápido, pero es importante conocer la técnica anterior (en código) por si fuera necesario en algunos casos complejos.

Lo primero que necesitamos para poder usar el control declarativamente es indi- car a la página nuestra intención, incluyendo el espacio de nombres apropiado dentro del cuerpo del hTML. Lo conseguimos con estos atributos:

<body

xmlns:sys=”javascript:Sys”

xmlns:dataview=”javascript:Sys.UI.DataView” sys:activate=”*”>

Lo que estamos declarando son dos espacios de nombres que nos servirán para escribir atributos especiales en los elementos hTML sin que el navegador “se queje”, y que la infraestructura de aJaX sepa interpretarlos. Los nombres después de xmlns son los prefijos para los atributos. así tendremos atributos sys y dataview. Puedes pensar en esto como en las directivas <@Register> de una página asPX que luego nos permiten usar controles de usuario en ellas.

el atributo sys:activate sirve para indicar en qué controles queremos utilizar los diferentes atributos (y por tanto controles) que estamos definiendo. si ponemos un asterisco, como en el ejemplo, estamos indicando que los queremos usar con cualquier elemento de la página. La otra opción es utilizar una lista de identifi- cadores de elementos separados por comas (por ejemplo: sys:activate=”productos-

template,txtNombre,txtApellidos”), que es más conveniente en páginas con mucho

hTML ya que ofrece mejor rendimiento.

al definir los espacios de nombres apropiados ya podemos asociar controles

DataView a plantillas con atributos hTML directamente, sin código. Por ejemplo

<tbody id=”Productos-template” class=”sys-template” sys:attach=”dataview” dataview:dataprovider=”Servicios/NorthwindService.svc” dataview:fetchoperation=”GetAllProducts” dataview:httpverb=”GET” dataview:autofetch=”true”> <tr> <td>{{ ProductName }}</td> <td>{{ UnitPrice }}</td> </tr> </tbody>

Fíjate que lo único que hay que hacer es adjuntar un control DataView a nuestro elemento contenedor de la plantilla gracias al atributo sys:attach. el resto son asig- naciones de propiedades para que el nuevo control pueda funcionar, las cuales se establecen con el prefijo dataview definido antes, seguido del nombre de la propiedad y el valor adecuado para cada una. así, en este ejemplo lo que estamos haciendo con las propiedades es:

Indicar que el proveedor de los datos es el servicio Web ubicado en “servi- •

cios/Northwindservice.svc”, relativa a la página actual.

Que el método que debe llamar para obtener los datos es “GetallProducts”. •

Que la llamada debe hacerla usando el método GeT, y no el método PosT •

que se usa por defecto. el motivo es que el servicio Web que hemos creado es de tipo resT (http://es.wikipedia.org/wiki/REST) y así lo requiere. Finalmente con la última propiedad le estamos diciendo que debe recoger •

automáticamente los datos y visualizarlos nada más crearse el control, para que no tengamos que forzarlo mediante código. así se obtendrán y enlazarán los datos nada más cargarse la página.

el orden en el que se asignen es indiferente. hacer esto es equivalente al código de inicialización que vimos antes, por lo que nos lo ahorramos y podemos hacer el enlazado de manera más sencilla y directamente en el hTML.

recapitulemos un momento todo lo que hemos necesitado:

Definimos el hTML de la plantilla indicando donde van sus campos y mar- 1.

cando con la clase sys-template al elemento contenedor de la misma. Declaramos en el cuerpo que queremos usar declarativamente el espacio de 2.

nombres Sys y el control Sys.UI.DataView, activando de paso los elementos que nos interesen.

activamos la plantilla asignando a su contenedor un control Dataview y 3.

como vemos es más sencillo y directo de lo que parece con todas las explicacio- nes intermedias, necesarias por otra parte. con esto ya tendríamos la funcionalidad deseada.

si ahora ejecutamos la página veremos que se visualizan los datos de los productos de manera asíncrona tras cargar la página. Lo único que hemos transferido desde el servidor son la página original (prácticamente vacía) y los datos que necesitábamos mostrar. Todo lo demás se ha hecho en el cliente con Javascript.

Figura 2.- la tabla resultante generada en el cliente

De momento no es muy espectacular, pero en los siguientes apartados iremos mejorando paulatinamente el ejemplo a medida que aprendemos más características del enlazado de datos en el cliente.

5.- PSEudo-coluMNAS y ATribuToS ESPEciAlES

vamos a mejorar un poco la visualización de nuestra tabla de datos con varias carac- terísticas adicionales. en primer lugar vamos a hacer que las columnas pares tengan un color diferente a las columnas impares. con este objetivo vamos aprenderemos a usar las pseudo-columnas de datos.

estas pseudo-columnas son campos especiales que se pueden utilizar en las plantillas y que nos ofrecen información de contexto sobre los datos que estamos enlazando. en concreto en la versión actual disponemos de las siguientes pseudo- columnas:

$index

: nos indica el número (basado en cero) del registro que el DataView está procesando actualmente.

$dataItem

: se trata de una referencia al objeto de datos que se está usando en este momento para generar la plantilla, por lo que podremos usarlo para obtener información sobre el mismo con reflexión, llamar a alguno de sus métodos o lo que pudiésemos necesitar.

$id(“identificador”)

: nos permite generar un identificador único para cada elemento de una plantilla, generado a partir de la cadena que se le pase. $element

: permite el acceso al elemento de la plantilla que se está proce- sando.

así, el primer añadido que vamos a hacer a nuestra tabla de datos es colocar una columna extra al principio de la misma que nos muestre el número de cada registro. Tras añadir la cabecera <th> correspondiente podemos incluir este código en la plantilla:

<td>{{ $index + 1 }}</td>

como $index está basado en cero le sumamos 1 para que tener una numeración más apropiada para el usuario.

otra característica que necesitaremos son unos atributos especiales para plantillas llamados atributos class. antes de poder usarlos debemos declararlos en el cuerpo de modo análogo a como lo hicimos antes con los prefijos sys y dataview. La etiqueta del cuerpo quedaría así:

<body

xmlns:sys=”javascript:Sys”

xmlns:dataview=”javascript:Sys.UI.DataView”

xmlns:class=”http://schemas.microsoft.com/aspnet/class” sys:activate=”*”>

a partir de este momento tenemos la capacidad de usar atributos class para establecer clases CSS condicionadas en los elementos de las plantillas. Lo que se consigue es asignar una clase css al elemento sólo en el caso de que se cumpla una determinada condición. en el ejemplo que nos ocupa vamos a usar una clase css para las columnas pares y otra diferente para las columnas impares, por lo que combinándolo con la pseudo-columna $index que acabamos de ver, la plantilla quedaría así: <tr class:impares=”{{ $index % 2 != 0 }}” class:pares=”{{ $index % 2 == 0 }}”> <td>{{ $index + 1 }}</td> <td>{{ ProductName }}</td> <td>{{ UnitPrice }}</td> </tr>

Fíjate que ahora la fila de la tabla tiene un par de atributos class. el primero asigna la clase css de nombre “impares” a aquellas filas cuyo índice no sea divisible entre dos (es código Javascript normal y corriente que usa el operador % para calcular el módulo de una división), y asigna la clase “pares” en caso contrario. De esta forma conseguimos un aspecto diferente en filas alternas de la tabla.