Compartir a través de


Aplicaciones modernas

Todo lo que necesita saber sobre el control ListView de WinJS

Rachel Appel

Rachel AppelUsted tiene datos. Muchos datos. Tiene que presentar estos datos de manera tal que los usuarios puedan acceder a ellos y entenderlos sin esfuerzo cuando usen su aplicación. Las aplicaciones exponen los datos en forma de artículos de noticias, recetas, marcadores deportivos, gráficos financieros y mucho más: todo un desfile por la pantalla de compartimentos de diferentes tamaños, cada uno de los cuales trata de atraer la atención del consumidor. La inmensa mayoría de las aplicaciones en el mercado actual presentan los datos en un formato de cuadrícula o de lista, ya que esto tiene sentido, debido a que los usuarios pueden consumir, buscar y filtrar fácilmente estas cuadrículas pequeñas o medianas con datos. Desde las aplicaciones empresariales, pasando por las aplicaciones personales, hasta el tipo de aplicación que sea, las cuadrículas son el andamiaje que apuntala los datos para un repaso visual rápido.

En las aplicaciones para la Tienda Windows, el control ListView nos permite configurar esta estructura para la presentación de datos. Si no tiene mucha experiencia con el desarrollo de aplicaciones para la Tienda Windows, puede ponerse al día con mi artículo de febrero de 2013, “Creación de una aplicación para la Tienda de Windows con HTML5 y JavaScript” (msdn.microsoft.com/magazine/jj891058) y mi artículo de julio de 2013, “Dominio de controles y configuraciones en aplicaciones de la Tienda Windows creadas con JavaScript” (msdn.microsoft.com/magazine/dn296546).

Fundamentos del control ListView

Disponible tanto en HTML como en XAML, ListView es el control de moda para presentar datos en forma de cuadrícula o lista. En las aplicaciones con la Biblioteca de Windows para JavaScript (WinJS) —el tema central de este artículo—, podemos usar el control ListView al establecer el atributo data-win-control en un elemento <div> contenedor en “WinJS.UI.ListView”:

<div id="listView" data-win-control= "WinJS.UI.ListView"></div>

El elemento <div> que hospeda el control ListView no contiene elementos secundarios. Sin embargo, contiene información básica de configuración en un atributo llamado data-win-options. Data-win-options nos permite establecer cualquier propiedad del control ListView mediante una sintaxis declarativa en la página HTML. Para usar el ListView correctamente, debemos aplicar las siguientes características:

  • Las plantillas de grupo y de elemento del ListView.
  • Los orígenes de grupo y de datos del ListView.
  • Si el ListView usa un diseño de cuadrícula o de lista (el estado predeterminado es la cuadrícula).

También deberíamos especificar si el modo de selección de elementos del ListView es singular o múltiple (el estado predeterminado es múltiple). Un ListView básico, donde las propiedades layout y selectionMode se establecen en el atributo data-win-options se ve así:

<div id="listView" data-win-control= "WinJS.UI.ListView" data-win-options=
  "{ selectionMode: 'single', layout : {type: WinJS.UI.GridLayout} }" ></div>

Aunque el código anterior define un ListView, este no funciona por su propia cuenta. Necesita la ayuda del objeto WinJS.Binding.List. El objeto List enlaza unas matrices rellenas con los objetos a los elementos HTML que se definen en las plantillas de elemento y grupo. Esto significa que el objeto List define los datos que se van a presentar, mientras que la plantilla define la forma en que se presentan.

Creación de plantillas de ListView

Una vez que tenemos configurado el <div> para el ListView, podemos pasar a crear las plantillas necesarias. El control ListView depende de plantillas HTML para mostrar los datos que verá el usuario. Afortunadamente, las plantillas Cuadrícula, En dos paneles y Concentrador (Concentrador está disponible en Windows 8.1) para las aplicaciones de la Tienda Windows contienen todo lo que necesitamos para presentar datos en formato de cuadrícula o lista, como datos de ejemplo, controles ListView predefinidos y clases CSS predefinidas. Usted puede modificar estas plantillas o crear las suyas propias, si prefiere. Tenga en cuenta, eso sí, que si crea sus propias plantillas, debe respetar los principios del diseño de Modern UI e implementar la silueta de Windows 8 tal como se describe en el Centro de desarrollo para las aplicaciones de la Tienda Windows (bit.ly/IkosnL). De esto se encargan automáticamente las plantillas integradas de Visual Studio.

ListView requiere de una plantilla de elemento, y si agrupamos los datos, entonces necesitamos también una plantilla de encabezado. Los elementos primarios de las plantillas de elemento y grupo son simples elementos <div>, donde el atributo data-win-control se establece en “WinJS.Binding.Template”.

La plantilla de encabezado debería contener vínculos para cada grupo que, al hacer clic, llevan al usuario a una página con un listado de los elementos que pertenecen a ese grupo. Este es un ejemplo de un patrón de navegación maestro y detalles bastante común. En la figura 1, el elemento <div> con la clase “headertemplate” contiene un elemento <button> enlazado a la clave del grupo. Si el usuario pulsa o hace clic en el botón, se traslada a una página con los miembros de ese grupo.

Figura 1 Plantillas de encabezado y elemento para el control ListView

<div class="headertemplate" data-win-control="WinJS.Binding.Template">
  <button class="group-header win-type-x-large win-type-interactive"
     data-win-bind="groupKey: key" 
     onclick="Application.navigator.pageControl
    .navigateToGroup(event.srcElement.groupKey)" 
     role="link" tabindex="-1"
     type="button">
    <span class="group-title win-type-ellipsis" data-win-bind=
      "textContent: title"></span>
    <span class="group-chevron"></span>
  </button>
</div>
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
  <div class="item">
    <img class="item-image" src="#" data-win-bind=
      "src: backgroundImage; alt: title" />
      <div class="item-overlay">
        <h4 class="item-title" data-win-bind="textContent: title"></h4>
        <h6 class="item-subtitle win-type-ellipsis" data-win-bind=
          "textContent: subtitle"></h6>
      </div>
  </div>
</div>

La plantilla de elemento de la figura 1 se compone de etiquetas <div> que encierran una imagen y dos campos de texto. Muchos de los datos que se encuentran en las aplicaciones de hoy son gráficos, así que hay un elemento <img> dentro de la plantilla de elemento. Los datos de ejemplo rellenan este elemento con una imagen gris uniforme. La figura 2 muestra el ListView del diseño de Cuadrícula.

The Default ListView from the Grid Template, with Heading and Navigation Buttons Marked in Red
Figura 2 Control ListView predeterminado de la plantilla de Cuadrícula, con los botones Heading y Navigation marcados en rojo

Después de codificar las plantillas de elemento y grupo, llegó el momento de conectarlas a los datos.

Datos y enlace de datos con el control ListView

JavaScript y JSON van mano en mano (JSON es la Notación de objetos de JavaScript, después de todo), así que una vez que recuperamos algunos datos de JSON, simplemente los colocamos en una matriz y el objeto Windows.Binding.List los convierte en un origen de datos usable para el ListView. En otras palabras, no enlazamos el control ListView directamente a una matriz o un origen de datos, lo que significa que el objeto List sirve de intermediario entre el ListView y el origen de datos. Esto se debe a que el objeto List transforma los datos en algo que ListView sabe usar; el ListView mismo solo define la apariencia y el diseño de la cuadrícula. El objeto List también proporciona los métodos necesarios para buscar, ordenar, agregar y eliminar miembros de la matriz subyacente.

Si examinamos el archivo \js\data.js, descubrimos el espacio de nombres Data, además de las matrices que componen los datos de ejemplo. El punto clave de todo esto es que ambas matrices se mezclan para formar una relación de maestro y detalles. La propiedad group de cada objeto en la matriz sampleItems (detalles) se refiere a su grupo en la matriz sampleGroups (maestro), tal como se aprecia en la figura 3.

Figura 3 Datos de ejemplo en forma de matriz en la plantilla de proyecto Cuadrícula

var sampleGroups = [
  { key: "group1", title: "Group Title: 1", 
     subtitle: "Group Subtitle: 1",
     backgroundImage: darkGray, description: groupDescription },
  { key: "group2", title: "Group Title: 2", 
     subtitle: "Group Subtitle: 2",
     backgroundImage: lightGray, description: groupDescription },
  { key: "group3", title: "Group Title: 3", 
     subtitle: "Group Subtitle: 3",
     backgroundImage: mediumGray, description: groupDescription }
];
var sampleItems = [
  { group: sampleGroups[0], title: "Item Title: 1",
    subtitle: "Item Subtitle: 1", 
    description: itemDescription,
     content: itemContent, backgroundImage: lightGray },
  { group: sampleGroups[0], title: "Item Title: 2",
     subtitle: "Item Subtitle: 2", 
     description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[0], title: "Item Title: 3", subtitle:
     "Item Subtitle: 3", 
     description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
  { group: sampleGroups[1], title: "Item Title: 1", subtitle:
     "Item Subtitle: 1", description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[2], title: "Item Title: 2", subtitle:
     "Item Subtitle: 2", description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
];

Por supuesto que usted reemplazará los datos del ejemplo con los suyos propios al crear sus propias matrices, acceder a datos en JSON o XML, o quizás al llamar a un servicio web. No está obligado a usar el espacio de nombres Data y puede, en vez de esto, definir el suyo propio.

Casi al principio del archivo data.js se encuentra la siguiente línea:

var list = new WinJS.Binding.List();

Esta variable de lista es un contenedor para una matriz. Podemos agregar una matriz a List al pasarla al método constructor de List o al usar el método push:

generateSampleData().forEach(function (item) {
  list.push(item);
});

Esto llena la lista con los datos de la matriz, con lo que estamos listos para asociar la lista con el ListView. Si usted se decanta por la plantilla predeterminada, entonces debería realizar esta asociación al principio, cuando la aplicación se carga, en la función _initializeLayout del archivo \js\default.js, tal como se aprecia aquí:

listView.itemDataSource = Data.items.dataSource;
listView.groupDataSource = Data.groups.dataSource;

Por supuesto, según el tamaño de los datos, el tiempo de carga puede variar, así que es posible que tenga que modificar el proceso de carga. Use su criterio sobre la carga de datos en memoria, teniendo en cuenta la importancia del rendimiento para los usuarios.

Observe que los orígenes de datos de elemento y grupo se establecen en Data.items.dataSource y Data.groups.dataSource, respectivamente. Los miembros llamados “elementos” y “grupos” del espacio de nombres Data se refieren a las funciones que crearon la matriz que contiene los datos (es decir, groupedItems). La declaración del espacio de nombres Data en el archivo \js\data.js refleja esta idea y muestra los miembros públicos en el espacio de nombres para trabajar con datos:

WinJS.Namespace.define("Data", {
  items: groupedItems,
  groups: groupedItems.groups,
  getItemReference: getItemReference,
  getItemsFromGroup: getItemsFromGroup,
  resolveGroupReference: resolveGroupReference,
  resolveItemReference: resolveItemReference
});

Los miembros de elementos y grupos del espacio de nombres Data apuntan al objeto groupedItems, que construyó los datos como corresponde. Todo lo que hemos visto en el espacio de nombres Data hasta aquí se incluye en las plantillas de proyecto de Visual Studio. Si usted opta por partir de un proyecto en blanco, deberá moldear los datos por su propia cuenta al crear métodos de acceso a datos similares en vez de valerse de los miembros del espacio de nombres Data.

En este punto, el ListView contiene los datos y los enlaces están configurados. Podemos enlazar las propiedades de los objetos en el origen de datos a elementos HTML mediante el atributo data-win-bind, tal como se aprecia aquí:

<h4 class="item-title" data-win-bind="textContent: title"></h4>

Esta línea de código enlaza la propiedad title al elemento <h4> como parte del texto. En la figura 1 y la figura 2 hay más ejemplos del atributo data-win-bind en acción.

Ahora que tenemos listo el ListView y el acceso a datos, llegó el momento de pasar a aplicar estilo al ListView.

Aplicación de estilo al control ListView

La presentación gira completamente en torno al estilo. Las bibliotecas de WinJS contienen un conjunto completo de reglas de CSS con estilos predefinidos que podemos sobrescribir para moldear el ListView de diferentes maneras. Si no tiene experiencia con la aplicación de estilos a los controles WinJS, consulte mi artículo de octubre de 2013, “Creación de una interfaz de usuario moderna y que responde bien con CSS para aplicaciones WinJS” (msdn.microsoft.com/magazine/dn451447). Para aplicar el estilo al ListView completo, podemos sobrescribir la clase CSS .win-listview. Junto con el estilo del ListView, podemos establecer las partes constituyentes del ListView mediante los siguientes selectores de clase:

  • .win-viewport: estilo de la ventanilla del ListView. La ventanilla es el lugar donde se encuentra la barra de desplazamiento.
  • .win-surface: estilo de la superficie desplazable del ListView. Esta área se desplaza cuando el usuario desplaza la barra.

Existen dos formas para aplicar estilos a los elementos en un ListView. Podemos aplicar estilos a la plantilla de elemento mediante la clase .win-item o podemos sobrescribir la clase .win-container. Tenga en mente que cada elemento en un ListView comprende varios elementos HTML (consulte estos elementos en la figura 1). Tal como se aprecia en la figura 1, los elementos <div> que componen la plantilla de elemento contienen una clase .item, .item-image, .item-overlay, .item-title y .item-subtitle. No encontrará ninguno de estos definidos en las hojas de estilos del sistema (es decir, ui-light y ui-dark), ya que la finalidad es que usted mismo aplique los estilos.

Debe tener conciencia de algunas artimañas con los estilos, especialmente sobre cuándo corresponde aplicar márgenes y espaciado interno al control ListView. Puede revisar los pormenores del estilo de ListView en el Centro de desarrollo para aplicaciones de la Tienda Windows en bit.ly/HopfUg. No olvide crear estilos para todos los diferentes estados de vista que puede necesitar la aplicación.

Windows 8.1 incluye algunos cambios en los estilos de ListView relacionados con la especificidad de los selectores de los elementos secundarios/descendientes. Esto se debe a que los nodos nuevos pertenecen a la estructura de árbol interna de la página, así que debemos actualizar los selectores CSS para que contengan el selector de clase .win-itembox, del siguiente modo: .win-container | .win-itembox | .win-item.

Respuesta a los cambios en el estado de vista en el ListView

Es importante responder a las nuevas vistas acoplada y rellena de Windows 8 para poder aprobar el proceso de certificación de la Tienda Windows. La vista acoplada, junto con las vistas completa y rellena, es cómo los usuarios pueden ordenar diferentes aplicaciones de la Tienda Windows en la pantalla. En Windows 8, los usuarios pueden cambiar el tamaño de hasta dos ventanas de aplicación, una en vista rellena y otra en vista acoplada. En Windows 8.1, la cantidad máxima de ventanas aumenta a cuatro y hay opciones nuevas para presentar las aplicaciones. Estas vistas se llaman alta y estrecha en Windows 8.1, y difieren ligeramente de las vistas acoplada y rellena de Windows 8.

Esto significa que debe codificar el control ListView para que cambie de formato en respuesta al estado de vista de la aplicación. Esto es un proceso llamado diseño dinámico y podemos lograrlo mediante consultas de medios de CSS. Para ver una introducción a las consultas de medios de CSS, consulte el artículo en mi blog, “Creación de diseños para sitios móviles con consultas de medios de CSS” (bit.ly/1c39mDx).

Las consultas de medios configuran al control ListView para que calce en los diferentes estados de vista, de modo que tenga sentido para los diferentes tamaños de pantalla y orientaciones que van con cada vista. Al cambiar a la vista alta, el ListView debe convertirse en una lista, del siguiente modo:

listView.layout = new ui.ListLayout();

Después, cuando el usuario vuelve al estado de vista original, debemos establecer el ListView de nuevo en cuadrícula:

listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });

Si quiere cambiar los estilos en los elementos del ListView cuando la pantalla cambia, agregue el siguiente CSS a esta consulta de medios en el archivo \css\default.css:

@media screen and (-ms-view-state: snapped) {...}

No necesitamos una consulta de medios para las vistas completa o rellena, ya que estas usan las hojas de estilo predeterminadas. Sin embargo, podemos usar consultas de medios diferentes para diferentes tamaños de pantalla si fuera necesario.

ListView y el zoom semántico

El rediseño de la versión 8 de Windows implica nuevas formas de visualizar, recorrer y buscar datos. Esto significa que debemos cambiar la forma en que nos enfrentarnos a la búsqueda. En vez de que el usuario tenga que escribir frases en un cuadro de búsqueda y examinar listas con resultados, ahora puede usar el zoom semántico para condensar los datos en secciones digeribles.

El zoom semántico permite que el usuario busque las cosas mediante un gesto de reducir (o Ctrl + rueda del mouse) para barrer horizontalmente o alejarse y observar los datos en un formato agregado. Por ejemplo, la página de inicio de Windows se comporta así al mostrar al usuario todas las aplicaciones disponibles cuando se alejan. Usar el zoom semántico en una aplicación es fácil, ya que es simplemente un control para WinJS:

<div data-win-control="WinJS.UI.SemanticZoom">
  <!-- The control that provides the zoomed-in view goes here. -->
  <!-- The control that provides the zoomed-out view goes here. -->
</div>

El control SemanticZoom es simplemente un contenedor para un ListView o dos, o quizás el nuevo control HTML Repeater de Windows 8.1.

De todo un poco sobre ListView

No use ListView como un control de diseño de uso general. Para esto, existe el modelo de cuadros de CSS. En Windows 8.1, debe considerar si le conviene más usar ListView o Repeater. El control Repeater es mejor si no requiere de una gran funcionalidad por parte del control y simplemente debe repetir el mismo diseño HTML varias veces. En el momento de redactar este artículo, Windows 8.1 se encuentra en la etapa de versión preliminar, así que podrían aparecer otros cambios en el ListView aparte de los otros componentes de la API de las aplicaciones para la Tienda Windows. Para obtener más información sobre los cambios en la API de Windows 8.1, consulte la documentación del Centro de desarrollo en bit.ly/1dYTylx.

Rachel Appel es consultora, autora, mentora y exempleada de Microsoft con más de 20 años de experiencia en la industria de TI. Es oradora en los más importantes congresos del sector, como Visual Studio Live!, DevConnections, MIX, entre otros. Se especializa en el desarrollo de soluciones que alinean los negocios con la tecnología y está enfocada en la pila de desarrollo de Microsoft y en la web abierta. Para obtener más información sobre Appel, visite su sitio web en rachelappel.com.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Eric Schmidt (Microsoft)
Eric Schmidt es desarrollador de contenidos en el equipo de Contenidos para desarrolladores de Microsoft Windows, donde escribe sobre la Biblioteca de Windows para JavaScript (WinJS). Anteriormente creó código de ejemplo para las aplicaciones de la plataforma de Office mientras se encontraba en la División de Microsoft Office. Aparte de esto dedica tiempo a su familia, toca el contrabajo, desarrolla videojuegos en HTML5 y escribe en un blog sobre juguetes de plástico (historybricks.com).