Empiece a realizar un seguimiento de su progreso
Inicio de Trailhead
Inicio de Trailhead

Utilizar controladores de lista estándar

Objetivos de aprendizaje

Después de completar esta unidad, podrá:
  • Explicar qué es un controlador de lista estándar de Visualforce y la diferencia entre él y un controlador (de registro) estándar.
  • Indicar tres acciones proporcionadas por el controlador de lista estándar que son diferentes a un controlador estándar.
  • Mostrar una lista de registros utilizando un controlador de lista estándar en una página de Visualforce.
  • Definir la paginación y poder agregarla a una página de Visualforce.

Introducción al controlador de lista estándar

El controlador de lista estándar le permite crear páginas de Visualforce que se pueden visualizar o en las que se pueden realizar acciones en un conjunto de registros.

La visualización de una lista de registros es un comportamiento fundamental de la mayoría de aplicaciones Web. Visualforce facilita mucho la tarea de mostrar una lista de registros del mismo tipo, utilizando solo marcas, sin códigos posteriores. El secreto, como de costumbre, es el controlador estándar, en este caso, el controlador de lista estándar.

El controlador de lista estándar proporciona muchos comportamientos automáticos y potentes, como solicitudes para registros de un objeto específico y hacer los registros disponibles en una variable de colección, así como el filtrado y la paginación en los resultados. La adición de un controlador de lista estándar a una página es muy similar a la adición del controlador (de registro) estándar, pero con la finalidad de trabajar con varios registros a la vez, en lugar de un solo registro a la vez.

Mostrar una lista de registros

Utilice el controlador de lista estándar y un componente de iteración, como <apex:pageBlockTable>, para mostrar una lista de registros.

El controlador (de registro) estándar facilita la obtención de un registro único cargado en una variable que puede utilizar en una página de Visualforce. El controlador de lista estándar es similar, excepto que en lugar de un registro único, carga una lista o conjunto de registros en la variable.

Como está frente a un conjunto, en vez de un registro individual, debe utilizar un componente de iteración para mostrarlos. Un componente de iteración funciona con un conjunto de elementos similares, en lugar de un solo valor. Un componente de iteración realiza un bucle a través de sus componentes, y para cada registro, genera algunos productos basándose en una plantilla que proporciona como parte de la marca del componente. Esto suena complicado en palabras, pero comprenderá rápido cuando lea la marca.

La marca para la utilización del controlador de lista estándar es casi idéntica a la utilización un controlador de un registro estándar único. Para hacerlo obvio, las diferencias principales se destacaran en negrita en el siguiente ejemplo.

  1. Abra Developer Console y haga clic en FileNew Visualforce Page (Archivo | Nuevo | Página de Visualforce) para crear una nueva página de Visualforce. Ingrese Lista de contactos para el nombre de página.
  2. En el editor, sustituya cualquier marca con lo siguiente.
    <apex:page standardController="Contact" recordSetVar="contacts">
        <apex:pageBlock title="Contacts List">
            <!-- Contacts List -->
            <apex:pageBlockTable value="{! contacts }" var="ct">
                <apex:column value="{! ct.FirstName }"/>
                <apex:column value="{! ct.LastName }"/>
                <apex:column value="{! ct.Email }"/>
                <apex:column value="{! ct.Account.Name }"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:page>
  3. Haga clic en Vista previa para abrir una vista previa de su página que podrá ver mientras realiza los cambios. Una nueva ventana se debe abrir, mostrando los elementos de barra lateral y encabezado de la página estándar de Salesforce y una lista de sus contactos. Una lista de contactos desde el controlador de lista estándar

La utilización de un controlador de lista estándar es muy similar a la utilización de un controlador estándar. Primero establece el atributo standardController en el componente <apex:page> y luego establece el atributo recordSetVar en el mismo componente. El atributo standardController establece el objeto con el que trabajar, justo como el controlar estándar. recordSetVar establece el nombre de la variable que crear con el conjunto de registros aquí {! contacts }. Convencionalmente, esta variable se denomina habitualmente el plural del nombre de objeto.

<apex:pageBlockTable> es un componente de iteración que genera una tabla de datos completa con estilo de plataforma. Esto es lo que sucederá en la marca de la tabla.
  • El atributo value de<apex:pageBlockTable> se establece como la variable cargada por el controlador de la lista estándar, {! contacts }. Esta es la lista de registros con la que trabajará <apex:pageBlockTable>.
  • Para cada registro en esa lista, registro por registro, <apex:pageBlockTable> asigna ese registro a la variable denominada en el atributo var de <apex:pageBlockTable>. En este caso, esa variable se denomina ct.
  • Para cada registro, <apex:pageBlockTable> crea una nueva fila en la tabla, utilizando la tabla definida por el conjunto de componentes <apex:column> en el cuerpo de <apex:pageBlockTable>. Los componentes de <apex:column>, a su vez, utilizan la variable ct que representa el registro actual que extrae los valores de campo para ese registro.
  • Fuera del círculo, <apex:pageBlockTable> utiliza los campos en los componentes <apex:column> para crear encabezados de columna buscando la etiqueta para cada campo.

Hay mucho que hacer y los componentes de iteración son difíciles de comprender la primera vez. Lo mejor que puede hacer ahora es intentar crear los suyos propios. Seleccione los campos que desea mostrar en la tabla. Busque los diferentes atributos para <apex:pageBlockTable> y <apex:column> y experimente hasta que se sienta cómodo. También puede probar con algunos de los otros componentes de iteración, como <apex:dataList> o incluso <apex:repeat>.

Agregar filtros de vista de lista a la lista

Utilice {! listViewOptions } para obtener una lista de filtros de vista de lista disponibles para un objeto. Utilice {! filterId } para establecer el filtro de vista de lista que se va a utilizar para los resultados de un controlador de lista estándar.

El controlador de lista estándar proporciona un número de funciones que puede utilizar para cambiar la visualización de la lista. Una de las más potentes es filtros de vista de lista. Crea filtros de vista de lista mediante declaración, utilizando clics en vez de códigos y el controlador de lista estándar le permite utilizar cualquier filtro de vista de lista definido en la página.

  1. Envuelva todo el <apex:pageBlock> en una etiqueta <apex:form> Para cambiar el filtro de vista de lista para un controlador de lista estándar, necesita enviar el nuevo valor de vuelta al servidor. La forma estándar de realzar este envío es utilizando un formulario creado utilizando el componente <apex:form>.
  2. En la etiqueta <apex:pageBlock>, agregue el siguiente atributo.
    id="contacts_list"
    Esto asigna a <apex:pageBlock> un “nombre” que podemos utilizar para un perfecto efecto Ajax que explicaremos en breve.
  3. Después de abrir la etiqueta <apex:pageBlock>, y después de <apex:pageBlockTable>, agregue la siguiente marca.
    Filter:
    <apex:selectList value="{! filterId }" size="1">
        <apex:selectOptions value="{! listViewOptions }"/>
        <apex:actionSupport event="onchange" reRender="contacts_list"/>
    </apex:selectList>
    El código completo para su página debe parecerse a esto.
    <apex:page standardController="Contact" recordSetVar="contacts">
        <apex:form>
            <apex:pageBlock title="Contacts List" id="contacts_list">
                Filter:
                <apex:selectList value="{! filterId }" size="1">
                    <apex:selectOptions value="{! listViewOptions }"/>
                    <apex:actionSupport event="onchange" reRender="contacts_list"/>
                </apex:selectList>
                <!-- Contacts List -->
                <apex:pageBlockTable value="{! contacts }" var="ct">
                    <apex:column value="{! ct.FirstName }"/>
                    <apex:column value="{! ct.LastName }"/>
                    <apex:column value="{! ct.Email }"/>
                    <apex:column value="{! ct.Account.Name }"/>
                </apex:pageBlockTable>
            </apex:pageBlock>
        </apex:form>
    </apex:page>
    Un nuevo control de filtros aparece encima de la lista. Lista de contactos con filtro de vistas de lista
  4. Seleccione un filtro diferente desde el menú. ¿Qué sucede con la lista de contactos?

Debe observar dos cosas cuando realiza una nueva selección desde el menú Filtro que acaba de crear. Primero, la lista de registros cambia cuando selecciona un nuevo filtro. (Es posible que necesite probar un par de opciones diferentes, algunas vistas de lista presentarán los mismos registros al utilizar los datos de muestra en una organización estándar de DE.)

En segundo lugar, y más sutil, es que la lista se actualiza sin volver a cargar toda la página. Este efecto “Ajax” es cortesía del atributo reRender="contacts_list" en el componente <apex:actionSupport>. El efecto combinado del componente y el reRender es actualizar solo la parte de la página denominada en el atributo reRender. Cuando agrega id="contacts_list" a <apex:pageBlock>, cuando se completa la acción, solo se actualiza <apex:pageBlock> sin volver a cargar la página por completo.

El ciclo de vida completo para las nuevas funciones en esta página será algo parecido a esto.
  • Cuando se carga la página, <apex:selectList> genera un menú de filtros disponibles, obteniendo la lista de la expresión {! listViewOptions }. listViewOptions es una propiedad proporcionada por el controlador de lista estándar.
  • Cuando selecciona una nueva opción del menú, el evento onchange se activa por el componente <apex:actionSupport>.
  • Cuando se activa onchange, la página envía la nueva vista de lista seleccionada, enviando el nuevo elemento a la propiedadfilterId, establecida en la <apex:selectList>.
  • Cuando se actualiza la propiedad, la página obtiene una nueva respuesta del servidor, con un nuevo conjunto de registros coincidentes en la variable contacts.
  • Pero como <apex:actionSupport> especifica volver a representar solo una parte de la página, la página se actualiza utilizando Ajax (JavaScript asíncrono) en vez de una nueva carga de página completa.

El efecto neto es que obtiene un comportamiento complejo y sofisticado agregando solo unas líneas de marca.

Agregar paginación a la lista

Utilice las funciones de paginación del controlador de lista estándar para permitir a los usuarios buscar listas largas de registros en una “página” al mismo tiempo.

Las funciones que desarrolló hasta el momento son geniales y funcionan bien con la lista breve de registros proporcionados como datos de muestra en una organización de Developer Edition. Pero, ¿qué sucede cuando tiene una organización real, con cientos o miles (o incluso millones) de registros? Buscarlos todos en una sola página no es una buena opción.

De hecho, el controlador de lista estándar, de forma predeterminada, solo muestra los primeros 20 registros que coinciden con su criterio de filtro, si existe. ¿Cómo puede ayudar a los usuarios a acceder a más de esos 20 primeros registros o quizás más registros por página que solo 20?

La respuesta es la paginación. Este es un elemento de la interfaz de usuario de la aplicación Web estándar, que le permite moverse hacia delante y hacia atrás en una lista larga de registros una “página” a la vez, habitualmente utilizando vínculos Siguiente y Anterior. Puede agregar esto a su página utilizando el controlador de lista estándar, o por comodidad, un indicador de progreso y un menú para cambiar el número de registros por página.

  1. Bajo la lista de contacto <apex:pageBlockTable>, agregue la siguiente marca.
    <!-- Pagination -->
    <table style="width: 100%"><tr>
        <td>
            <!-- Page X of Y -->
        </td>
        <td align="center">
            <!-- Previous page -->
            <!-- Next page -->
        </td>
        <td align="right">
            <!-- Records per page -->
        </td>
    </tr></table>
    Esto crea una tabla HTML que contendrá los tres controles de paginación que va a agregar. Nota En sus páginas reales, puede utilizar más marcas semánticas con estilos separados, pero por el momento, el código HTML sin formato es conciso y elimina los pasos innecesarios.
  2. Sustituya la línea de comentario <!-- Page X of Y --> con la siguiente marca.
    Page: <apex:outputText
        value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>
    Esto agrega un indicador de progreso a la lista, indicando qué página está visualizando el usuario y cuántas más hay. Si está intentando esto en una organización de DE, es probable que diga “Página 1 de 1”.
  3. Sustituya las líneas de comentario <!-- Previous page --> y <!-- Next page --> con la siguiente marca.
    <!-- Previous page -->
    <!-- active -->
    <apex:commandLink action="{! Previous }" value="« Previous"
         rendered="{! HasPrevious }"/>
    <!-- inactive (no earlier pages) -->
    <apex:outputText style="color: #ccc;" value="« Previous"
         rendered="{! NOT(HasPrevious) }"/>
    &nbsp;&nbsp;
    <!-- Next page -->
    <!-- active -->
    <apex:commandLink action="{! Next }" value="Next »"
         rendered="{! HasNext }"/>
    <!-- inactive (no more pages) -->
    <apex:outputText style="color: #ccc;" value="Next »"
         rendered="{! NOT(HasNext) }"/>
    Esta marca proporciona vínculos Anterior y Siguiente en la página. La marca cubre dos posibilidades: cuando hay más registro para ver en una dirección concreta, entonces el vínculo está activo; y cuando no hay más páginas en una dirección concreta, el vínculo está desactivado.
  4. Sustituya la línea de comentario <!-- Records per page --> con la siguiente marca.
    Records per page:
    <apex:selectList value="{! PageSize }" size="1">
        <apex:selectOption itemValue="5" itemLabel="5"/>
        <apex:selectOption itemValue="20" itemLabel="20"/>
        <apex:actionSupport event="onchange" reRender="contacts_list"/>
    </apex:selectList>
    Esta marca proporciona un menú para cambiar el número de registros por página. Aquí solo agregamos una opción para mostrar menos registros en una página. Seleccione “5” de la lista y vea qué sucede en la lista y los otros controles.
Los resultados consisten en una página de lista con bastantes pocas funciones proporcionadas por el controlador de lista estándar.
Lista de contactos con controles de paginación

En el indicador de progreso, se utilizan tres propiedades para indicar el número de páginas: PageNumber, ResultSize y PageSize. Las dos últimas se utilizan actualmente en una expresión de fórmula que redondea el número al número entero más próximo. Esto evita que el indicador proporcione algún disparate, como “Página 2 de 1.6”.

En los controles de paginación, los componentes <apex:commmandLink> hacen referencia a dos métodos de acción proporcionados por el controlador de lista estándar, Anterior y Siguiente. El resultado es un vínculo que realiza la acción Anterior o Siguiente.

Pero, ¿qué es este atributo rendered, con expresiones como {! HasPrevious }? Así es cómo Visualforce le permite mostrar componentes de forma condicional, o sea, dependiendo del resultado de una expresión booleana. Aquí, la marca de la página hace referencia a propiedades booleanas proporcionadas por el controlador de lista estándar, HasPrevious y HasNext, lo que permite saber si hay más registros en una dirección concreta o no. Utilizando la expresión en el atributo rendered, puede mostrar u ocultar los resultados de ese componente en la página. Así es cómo el vínculo Anterior aparece en gris cuando carga la página por primera vez, pero se vuelve activo cuando se mueve hacia adelante haciendo clic en el vínculo Siguiente.

El menú de selección registros por página utiliza <apex:selectList>, que utilizó anteriormente, pero en vez de llamar un método de controlador para obtener valores del menú, simplemente utilizamos elementos <apex:selectOption> para los valores deseados. De nuevo, la etiqueta <apex:actionSupport> hace que el menú active su acción siempre que cambie el valor seleccionado y de nuevo utiliza reRender="contacts_list" para actualizar solo<apex:pageBlock>. La nueva parte aquí es que <apex:selectList> establece la propiedad PageSize del controlador de lista estándar.

Más información...

El controlador de lista estándar proporciona varias funciones comunes en aplicaciones Web, más de las que se han tratado aquí.

Por ejemplo, además de las acciones Anterior y Siguiente, que mueven una página hacia delante y hacia atrás al mismo tiempo, existen también las acciones Primero y Último que van al principio o al final de la lista de registros.

En el segundo plano de su marca, el controlador de lista estándar está basado en la clase StandardSetController Apex. Puede leer más acerca de ello y todas las funciones que proporciona en la Guía del desarrollador de código Apex de la Plataforma Lightning.

Hay un problema obvio con los ejemplos que creamos aquí y su nombre es clasificación. Es a menudo deseable tener un orden de clasificación predeterminado para una lista y también tener encabezados de columna que afectan a la clasificación y que permiten cambiar el orden de la clasificación sobre la marcha. Lo cierto es que no puede alterar el orden de la clasificación utilizando solo Visualforce. Aunque la cantidad de marcas adicionales de Visualforce y códigos Apex necesaria para los encabezados de columna activables y de clasificación no es grande, requiere códigos personalizados. Consulte los recursos adicionales para algunos puntos de inicio.