• No results found

2.4 Decision Process on Source to Buy and How to Buy

2.4.2 Determining merchandise selection techniques

Del mismo modo que podemos asignar clases de manera condicional, existen unos atributos especiales del espacio de nombres sys que trabajan de manera parecida. en este caso lo que nos permiten es establecer algunos atributos comunes de los elementos hTML. se trata de los siguientes:

sys:checked

: se usa para generar el atributo checked de los elementos hTML que lo soportan, indicando una condición para ello. Lo usaremos ahora mis- mo en nuestro ejemplo.

sys:disabled

: idem que el anterior pero para el atributo disabled que permite desactivar controles.

sys:id

: se usa para generar identificadores de elementos mediante código Ja- vascript. Por ejemplo, para generar un identificador a partir del identificador de producto podríamos escribir: sys:id=”{{ ‘Prod_’ + ProductID }}”. sys:src

: para generar atributos src a partir de código. Muy útil por ejemplo para colocar rutas a imágenes sacadas de una base de datos.

sabiendo esto vamos a añadir una columna más a nuestra plantilla para que se visualice el estado de disponibilidad de cada producto. hay un campo en la base de datos llamado Discontinued, que es verdadero si el producto está descatalogado. Podemos aprovecharlo para mostrar esta información usando un checkbox de hTML, mediante un atributo sys condicional del siguiente modo:

<td>

<input type=”checkbox” disabled=”disabled” sys:checked=”{{ Discontinued }}” />

</td>

es decir, que sólo aparecerá marcado si el valor del campo Discontinued es

true.

con estos cambios nuestra nueva plantilla mostrará la lista de productos de la manera que se observa en la figura 3.

Figura 3.- tabla resultante de nuestra plantilla mejorada.

7.- ATribuToS code PArA rENdEriZAdo

coNdicioNAl

Una cuestión habitual al generar hTML en el cliente es que necesitemos que algunos elementos se creen sólo al cumplirse ciertas condiciones. Por ejemplo, al enlazar datos a una lista desplegable que actuará de filtro para otra tabla, si nos encontramos en el primer elemento que también se renderice un elemento adicional vacío que sirva para deshacer el filtro. este ejemplo en concreto lo tienes en el código del ZIP, en la página “Default.aspx”.

Las variantes de este atributo son tres: code:if

: si el resultado del código de este atributo es verdadero se renderizará el elemento, obviándolo de la interfaz en caso contrario.

code:before

: ejecutará, justo antes de procesar el elemento para la plantilla, el código Javascript que le asignemos como valor. Útil para hacer cosas durante el procesamiento que puedan afectar al resto de la plantilla.

code:after

: idem que el anterior, pero ejecutando el código al terminar de procesar el elemento actual.

estos atributos son muy útiles cuando los combinamos con las pseudo-columnas que estudiamos anteriormente.

Para poder utilizarlos hay que declarar su espacio de nombres en la etiqueta

body, con lo que nos quedaría de la siguiente forma (ahora es el tercer espacio de

nombres declarado): <body xmlns:sys=”javascript:Sys” xmlns:dataview=”javascript:Sys.UI.DataView” xmlns:code=”http://schemas.microsoft.com/aspnet/code” xmlns:class=”http://schemas.microsoft.com/aspnet/class” sys:activate=”*”>

vamos a aprovechar estos atributos para añadir a nuestra tabla de datos una indicación visual sobre el stock actual de los productos. vamos a indicar tres niveles diferentes: verde, naranja y rojo, según si tenemos mucho stock, poco o ninguno en absoluto. el valor del inventario lo conocemos gracias al campo de la base de datos llamado UnitsInStock.

añadiremos una nueva columna a la tabla que contendrá la definición de los tres niveles de stock con sendas imágenes:

<td>

<img src=”Images/stock_ok.gif” code:if=” UnitsInStock >= 20 “ /> <img src=”Images/stock_m.gif” code:if=” UnitsInStock < 20 && UnitsInStock > 0” />

<img src=”Images/stock_ko.gif” code:if=” UnitsInStock == 0 “ /> </td>

hemos incluido en cada una de ellas un atributo code:if con una condición que define cuándo debe generarse el elemento en la plantilla. De este modo si el stock actual del producto es superior a 20 unidades, consideramos que tenemos mucho y se mostrará una marca de verificación de color verde. si es mejor de 20, indicaremos un stock mermado con una admiración naranja. Finalmente si no hay stock se indicará mediante un aspa roja.

estas expresiones nos dan mucho juego para determinar qué elementos queremos mostrar en cada momento y también para actuar sobre variables globales o sobre elementos que se van a procesar a continuación o que acaban de renderizarse.

8.- ENlAZAdo dE dAToS EN TiEMPo rEAl

hasta ahora hemos enlazado objetos usando la sintaxis de la doble llave {{ }}, cono- cida como evaluador de expresiones en línea. como deducimos de su nombre, su objetivo es evaluar las expresiones Javascript que hayamos escrito dentro. Una vez hecho esto no hay ningún tipo de relación posterior con los elementos subyacentes. De hecho podemos utilizarlas para evaluar cualquier tipo de expresión Javascript, no es necesario que sea una propiedad del objeto que estamos enlazando.

el uso de esta sintaxis nos otorga un gran poder, pero ofrece una limitación fundamental: el enlace se realiza sólo una vez, al procesar la plantilla. Una vez visualizada la información, si se produce cualquier cambio en los datos subyacentes, éste no se verá reflejado en la interfaz.

La funcionalidad de plantillas de asP.NeT aJaX permite mantener sincroniza- dos, en tiempo real, los datos enlazados y la interfaz de usuario. De esta manera si la información varía (porque la hemos editado en otro lugar de la página, por ejemplo), sus nuevos valores se ven reflejados de inmediato en todas las plantillas que los usen. esta funcionalidad se basa en el uso del patrón de diseño Observer, gran conocido por los programadores aficionados a la arquitectura de software, y en especial los que vienen del mundo Java.

el enlazado a datos en las plantillas tiene una sintaxis alternativa que habilita el refresco en tiempo real de la interfaz. en lugar de usar una doble llave, se emplea una llave simple junto con la palabra clave binding. es decir, en lugar de escribir:

{{ ProductName }}

escribiremos

{binding ProductName }

y automáticamente, a partir de ese momento, si cambia el valor del nombre de producto, este cambio se verá reflejado automáticamente en la interfaz generada a partir de la plantilla. Y todo esto sin tener que escribir ni una línea de código.

esta característica se denomina Live Binding o Enlazado en Tiempo Real. Nota:

No vamos a entrar en detalle aquí sobre el funcionamiento de este patrón, pero baste decir que es suficiente utilizar una llamada al método makeObservable de la clase Sys.Observer (inclui- do por las extensiones de Javascript de asP.NeT aJaX), para que automáticamente nuestro objeto genere eventos ante todos los cambios que se produzcan en sus propiedades. Y esto es independiente de la funcionalidad de plantillas por lo que podemos sacarle partido en nuestros propios desarrollos para otras cosas.

Dependiendo del elemento hTML al que enlacemos los datos, el enlace puede ser en un solo sentido (single-way) o bidireccional (two-way).

Por ejemplo si enlazamos un campo a un control input de texto, lo que escribamos en éste hará que se modifique el valor subyacente, modificando los datos originales. sería un enlace bidireccional, puesto que los cambios en el objeto se reflejan en el control y viceversa. sin embargo si lo enlazamos a un elemento de sólo lectura (por ejemplo a un <span>), el enlace sólo será posible en un sentido, ya que el elemento al no cambiar no puede afectar a los datos originales.

Todo esto nos resultará de gran ayuda para enviar información modificada al servidor como veremos enseguida.

Mientras tanto vamos a ver un ejemplo rápido de uso que, si bien no será muy útil, nos dará una idea precisa de cómo funciona el Live Binding. Para ello enlazaremos una plantilla a un elemento de la página, y no a un origen de datos. así también veremos cómo se puede usar para muchas más cosas que para enlazarnos a datos traídos desde el servidor.

arrastremos un control de texto hTML (<input>) a la página. a continuación, dentro de un <span> que actuará de contenedor de nuestra plantilla, definiremos otro <span> y un nuevo control de texto. La sintaxis final será esta:

<input type=”text” id=”txtOrigen” value=”” />&nbsp; <span id=”textoEnlazado” class=”sys-template” sys:attach=”dataview”

dataview:data=”{{ $get(‘txtOrigen’) }}”> <span>{binding value}</span>&nbsp;

<input type=”text” id=”txtCopia” value=”{binding value}” />

</span>

en este caso usamos el dataView para enlazarnos directamente contra el primer cuadro de texto. aquí no hay datos traídos del servidor ni código alguno, sólo sin- taxis declarativa. Fíjate que no hay tampoco código de servidor, y que podríamos haber usado una página con extensión .htm siempre que incluyamos los scripts de asP.NeT aJaX como archivos externos y no con un ScriptManager.

en la parte correspondiente a la plantilla hemos usado Live Binding para mos- trar el valor del campo de texto (propiedad value de éste, por eso se escribe

Nota:

este ejemplo lo tienes en las descargas del libro, dentro de la carpeta correspondiente a las plantillas de datos (vs2010_PlantillasDatoscliente_aJaX), en el archivo llamado “BindingenDossentidos_ejBasico.aspx”.

{ binding value }) en una etiqueta (<span>) y en otro cuadro de texto. ¿Qué ocurrirá al ejecutarlo?

abre la página y juega con ella un poco. verás que todo lo que escribas en el primer cuadro de texto se verá automáticamente reflejado en los otros dos elementos en cuanto quites el foco de él. al mismo tiempo, como el segundo cuadro de texto tiene un enlace bidireccional con el primero, al escribir algo en él y quitarle el foco, el cambio aparecerá de inmediato en el primero y en la etiqueta.

en la práctica lo que hemos conseguido es mantener sincronizados ambos cua- dros de texto y la etiqueta. Fíjate además que la propia infraestructura de aJaX se ocupa de evitar que entremos en un bucle de cambios infinitos cuando uno cambia al otro.

esta funcionalidad nos otorga un enorme poder para el manejo de datos en el clien- te, y en los próximos apartados vamos a ver cómo sacarle todo el partido posible.

9.- viSTAS MAESTro-dETAllE: PrEPArAr El

MAESTro

vamos a seguir mejorando nuestro ejemplo para, al mismo tiempo, aprender nuevas características de las plantillas de lado cliente. en esta ocasión vamos a añadirle la posibilidad de mostrar un detalle de los registros al pulsar sobre ellos. se trata de la típica vista maestro-detalle que hay en casi todas las aplicaciones: facturas-líneas de factura, proveedor-artículos, etc... en esta ocasión vamos a mostrar en otro lugar de la página, con una nueva plantilla, los datos seleccionados en nuestra lista de productos.

Lo primero que vamos a ver es de qué manera podemos provocar la selección. existen tres atributos especiales del espacio de nombres Sys que están especializados en generar acciones para los elementos de las plantillas. se trata de:

sys:command

: el nombre del comando que queremos lanzar. actualmente el único comando estándar existente es “select” para seleccionar elementos. Podemos, no obstante, emplear cualquier otra cadena arbitraria para definir comandos propios, y así generar eventos adaptados a nuestras necesidades. sys:commandargument

: argumentos que queremos pasarle al comando, para particularizarlo. Quizá un identificador, una referencia a un elemento, etc... sys:commandtarget

: el elemento sobre el que queremos actuar. Normalmente no se utiliza.

en nuestro ejemplo vamos a hacer que se seleccione el producto actual en el momento en el que el usuario pulse sobre cualquier punto de fila de la tabla de productos. redefinimos la fila (elemento <tr> en nuestro ejemplo) añadiéndole el atributo sys:command, así

esto provoca que el procesador de plantillas incluya el Javascript necesario para conseguir ese efecto. el evento de selección es automáticamente reconocido por el control dataView.

si ahora probamos el ejemplo, lo cierto es que no notaremos diferencia alguna con lo que ya teníamos. Necesitamos algo más para que se manifieste visiblemente la selección.

el control dataView está diseñado para trabajar en equipo con sys:command, y dispone de una propiedad llamada selectedItemClass. Ésta sirve para asignar auto- máticamente un estilo css al elemento que provoca el comando.

Define en la página del ejemplo una nueva clase css, de nombre “.seleccionado”, que establezca el color de fondo en un tono que destaque sobre los restantes utiliza- dos en la página. ahora añade este atributo al elemento contenedor de la plantilla:

dataview:selecteditemclass=”seleccionado”

ejecuta de nuevo la aplicación. ahora sí que seleccionarás de manera visible cada fila, ya que al hacer clic sobre una de ellas ésta adoptará el estilo de nombre “seleccionado”.

Los datos que queremos visualizar como vista de detalle de nuestros productos son los campos del producto actualmente seleccionado. Los dataView tienen una propiedad llamada selectedData que devuelve precisamente esta información. Ne- cesitamos alguna manera de identificar al dataView de los productos para poder acceder a sus propiedades y así poder leer los datos del elemento seleccionado.

aquí es donde entra el último atributo que veremos dentro del espacio de nombres de sistema: sys:key. con él podemos asignar de manera declarativa identificadores Javascript a los componentes, como el dataView, que activemos en los elementos hTML.

Para otorgar un nombre a nuestro dataView de productos añadiremos el siguiente atributo al elemento contenedor de la plantilla de productos (míralo en el código de ejemplo):

dataview:sys-key=”TablaProductos”

De este modo a partir de ahora podremos acceder a este dataview desde otros elementos de plantillas utilizando el identificador que le hemos asignado, en este caso “TablaProductos”. Fíjate en que como se está aplicando un sys:key como atri- buto secundario de dataView, se usa un guión y no dos puntos en la declaración anterior: dataview:sys-key.

10.- viSTAS MAESTro-dETAllE: PrEPArAr loS