Para paginar elementos en páginas, Zend_Paginator
debe disponer de una forma genérica de acceder a esos datos. Por esa razón,
todo el acceso a los datos se realiza a través de adaptadores de origen de datos. Varios
adaptadores se incluyen con Zend Framework por defecto:
Tabla 54.1. Adaptadores para Zend_Paginator
| Adaptador | Descripción |
|---|---|
| Array | Usar un array de PHP |
| DbSelect |
Usar una instancia de Zend_Db_Select,
que devolverá un array
|
| DbTableSelect |
Usar una instancia de Zend_Db_Table_Select,
que devolverá una instancia de
Zend_Db_Table_Rowset_Abstract.
Esto proporciona información adicional sobre el
conjunto de resultados, como los nombres de columnas.
|
| Iterator |
Usar una instancia de Iterator
|
| Null |
No usar Zend_Paginator para gestionar
la paginación de datos. Aun así, puede aprovechar
la funcionalidad de control de paginación.
|
![]() |
Nota |
|---|---|
|
En lugar de seleccionar todas las filas coincidentes de una consulta dada, los adaptadores DbSelect y DbTableSelect recuperan únicamente la cantidad mínima de datos necesaria para mostrar la página actual.
Debido a esto, se genera dinámicamente una segunda consulta para
determinar el número total de filas coincidentes. Sin embargo, es
posible proporcionar directamente un conteo o una consulta de conteo usted mismo.
Consulte el método |
Para crear una instancia de Zend_Paginator, debe
proporcionar un adaptador al constructor:
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array));
Por conveniencia, puede aprovechar el método estático
factory() para los adaptadores incluidos con Zend
Framework:
$paginator = Zend_Paginator::factory($array);
![]() |
Nota |
|---|---|
En el caso del adaptador |
Aunque la instancia es técnicamente utilizable en este estado, en su acción de controlador deberá indicar al paginador qué número de página solicitó el usuario. Esto le permite avanzar a través de los datos paginados.
$paginator->setCurrentPageNumber($page);
La forma más sencilla de llevar el control de este valor es a través de una URL.
Aunque recomendamos usar un
enrutador compatible con Zend_Controller_Router_Interface
para gestionar esto, no es un requisito.
A continuación se muestra un ejemplo de ruta que podría usar en un archivo de configuración INI:
routes.example.route = articles/:articleName/:page routes.example.defaults.controller = articles routes.example.defaults.action = view routes.example.defaults.page = 1 routes.example.reqs.articleName = \w+ routes.example.reqs.page = \d+
Con la ruta anterior (y usando los componentes MVC de Zend Framework), podría establecer el número de página actual de esta manera:
$paginator->setCurrentPageNumber($this->_getParam('page'));
Hay otras opciones disponibles; consulte Configuración para más información sobre ellas.
Finalmente, deberá asignar la instancia del paginador a su vista.
Si está usando Zend_View con el helper de acción ViewRenderer,
lo siguiente funcionará:
$this->view->paginator = $paginator;
El uso de la mayoría de adaptadores es bastante sencillo. Sin embargo, los adaptadores de base de datos requieren una explicación más detallada respecto a la recuperación y el conteo de los datos desde la base de datos.
Para usar los adaptadores DbSelect y DbTableSelect no es necesario recuperar los datos
de antemano desde la base de datos. Ambos adaptadores realizan la recuperación por usted, así como el
conteo del total de páginas. Si es necesario realizar trabajo adicional sobre los resultados de la base de datos,
el método getItems() del adaptador debe extenderse en su
aplicación.
Además, estos adaptadores no obtienen todos los registros de la
base de datos para contarlos. En su lugar, los adaptadores manipulan la consulta original para
producir la consulta COUNT correspondiente. Paginator ejecuta entonces esa consulta COUNT para obtener
el número de filas. Esto requiere un viaje adicional a la base de datos, pero muchas veces
es más rápido que obtener un conjunto de resultados completo y usar
count(). Especialmente con grandes colecciones de datos.
Los adaptadores de base de datos intentarán construir la consulta más eficiente que se ejecute en prácticamente todas las bases de datos modernas. Sin embargo, dependiendo de su base de datos o incluso de su propia configuración de esquema, puede haber formas más eficientes de obtener un conteo de filas. Para este escenario, los adaptadores de base de datos le permiten establecer una consulta COUNT personalizada. Por ejemplo, si lleva el conteo de publicaciones de blog en una tabla separada, podría lograr una consulta de conteo más rápida con la siguiente configuración:
$adapter = new Zend_Paginator_Adapter_DbSelect($db->select()->from('posts'));
$adapter->setRowCount(
$db->select()
->from(
'item_counts',
array(
Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'post_count'
)
)
);
$paginator = new Zend_Paginator($adapter);
Este enfoque probablemente no le proporcione una gran mejora de rendimiento en colecciones pequeñas y/o consultas select simples. Sin embargo, con consultas complejas y grandes colecciones, un enfoque similar podría proporcionarle un aumento de rendimiento significativo.
El script de vista se usa para renderizar los elementos de la página (si está usando
Zend_Paginator para hacerlo) y mostrar el control
de paginación.
Dado que Zend_Paginator implementa la interfaz SPL
IteratorAggregate,
recorrer sus elementos y mostrarlos es sencillo.
<html>
<body>
<h1>Example</h1>
<?php if (count($this->paginator)): ?>
<ul>
<?php foreach ($this->paginator as $item): ?>
<li><?php echo $item; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php echo $this->paginationControl($this->paginator,
'Sliding',
'my_pagination_control.phtml'); ?>
</body>
</html>
Observe la llamada al helper de vista cerca del final. PaginationControl acepta hasta cuatro parámetros: la instancia del paginador, un estilo de desplazamiento, un partial de vista, y un array de parámetros adicionales.
El segundo y tercer parámetro son muy importantes. Mientras que el partial de vista se usa para determinar cómo debe verse el control de paginación, el estilo de desplazamiento se usa para controlar cómo debe comportarse. Suponga que el partial de vista está en el estilo de un control de paginación de búsqueda, como el siguiente:
¿Qué sucede cuando el usuario hace clic en el enlace "siguiente" varias veces? Bueno, podría suceder cualquier cantidad de cosas. El número de página actual podría permanecer en el centro mientras hace clic (como sucede en Yahoo!), o podría avanzar hasta el final del rango de páginas y luego volver a aparecer a la izquierda cuando el usuario haga clic en "siguiente" una vez más. Los números de página incluso podrían expandirse y contraerse mientras el usuario avanza (o "se desplaza") a través de ellos (como en Google).
Hay cuatro estilos de desplazamiento incluidos con Zend Framework:
Tabla 54.2. Estilos de desplazamiento para Zend_Paginator
| Estilo de desplazamiento | Descripción |
|---|---|
| All | Devuelve todas las páginas. Esto es útil para controles de paginación de menú desplegable con relativamente pocas páginas. En estos casos, se desea tener todas las páginas disponibles para el usuario a la vez. |
| Elastic | Un estilo de desplazamiento al estilo de Google que se expande y se contrae mientras el usuario se desplaza por las páginas. |
| Jumping | A medida que los usuarios se desplazan, el número de página avanza hasta el final de un rango dado, y luego comienza de nuevo al principio del nuevo rango. |
| Sliding | Un estilo de desplazamiento al estilo de Yahoo! que posiciona el número de página actual en el centro del rango de páginas, o lo más cerca posible. Este es el estilo predeterminado. |
El cuarto y último parámetro está reservado para un array asociativo opcional
de variables adicionales que desee tener disponibles
en su partial de vista (disponible mediante $this). Por
ejemplo, estos valores podrían incluir parámetros de URL adicionales para
los enlaces de paginación.
Estableciendo el partial de vista predeterminado, el estilo de desplazamiento predeterminado, y la instancia de vista, puede eliminar por completo las llamadas a PaginationControl:
Zend_Paginator::setDefaultScrollingStyle('Sliding');
Zend_View_Helper_PaginationControl::setDefaultViewPartial(
'my_pagination_control.phtml'
);
$paginator->setView($view);
Cuando todos estos valores están establecidos, puede renderizar el control de paginación dentro de su script de vista con una simple sentencia echo:
<?php echo $this->paginator; ?>
![]() |
Nota |
|---|---|
|
Por supuesto, es posible usar
$smarty->assign('pages', $paginator->getPages());
Podría entonces acceder a los valores del paginador desde una plantilla de esta manera:
{$pages->pageCount}
|
Los siguientes ejemplos de controles de paginación esperamos que le ayuden a comenzar:
Paginación de búsqueda:
<!--
See http://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination
-->
<?php if ($this->pageCount): ?>
<div class="paginationControl">
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< Previous
</a> |
<?php else: ?>
<span class="disabled">< Previous</span> |
<?php endif; ?>
<!-- Numbered page links -->
<?php foreach ($this->pagesInRange as $page): ?>
<?php if ($page != $this->current): ?>
<a href="<?php echo $this->url(array('page' => $page)); ?>">
<?php echo $page; ?>
</a> |
<?php else: ?>
<?php echo $page; ?> |
<?php endif; ?>
<?php endforeach; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
Next >
</a>
<?php else: ?>
<span class="disabled">Next ></span>
<?php endif; ?>
</div>
<?php endif; ?>
Paginación de elementos:
<!--
See http://developer.yahoo.com/ypatterns/pattern.php?pattern=itempagination
-->
<?php if ($this->pageCount): ?>
<div class="paginationControl">
<?php echo $this->firstItemNumber; ?> - <?php echo $this->lastItemNumber; ?>
of <?php echo $this->totalItemCount; ?>
<!-- First page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->first)); ?>">
First
</a> |
<?php else: ?>
<span class="disabled">First</span> |
<?php endif; ?>
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< Previous
</a> |
<?php else: ?>
<span class="disabled">< Previous</span> |
<?php endif; ?>
<!-- Next page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
Next >
</a> |
<?php else: ?>
<span class="disabled">Next ></span> |
<?php endif; ?>
<!-- Last page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->last)); ?>">
Last
</a>
<?php else: ?>
<span class="disabled">Last</span>
<?php endif; ?>
</div>
<?php endif; ?>
Paginación desplegable:
<?php if ($this->pageCount): ?>
<select id="paginationControl" size="1">
<?php foreach ($this->pagesInRange as $page): ?>
<?php $selected = ($page == $this->current) ? ' selected="selected"' : ''; ?>
<option value="<?php
echo $this->url(array('page' => $page));?>"<?php echo $selected ?>>
<?php echo $page; ?>
</option>
<?php endforeach; ?>
</select>
<?php endif; ?>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
</script>
<script type="text/javascript">
$('paginationControl').observe('change', function() {
window.location = this.options[this.selectedIndex].value;
})
</script>
Las siguientes opciones están disponibles para los partials de vista de control de paginación:
Tabla 54.3. Propiedades disponibles para los partials de vista
| Propiedad | Tipo | Descripción |
|---|---|---|
| first | integer | Número de la primera página (por ejemplo, 1) |
| firstItemNumber | integer | Número absoluto del primer elemento de esta página |
| firstPageInRange | integer | Primera página en el rango devuelto por el estilo de desplazamiento |
| current | integer | Número de página actual |
| currentItemCount | integer | Número de elementos en esta página |
| itemCountPerPage | integer | Número máximo de elementos disponibles por página |
| last | integer | Número de la última página |
| lastItemNumber | integer | Número absoluto del último elemento de esta página |
| lastPageInRange | integer | Última página en el rango devuelto por el estilo de desplazamiento |
| next | integer | Número de la página siguiente |
| pageCount | integer | Número de páginas |
| pagesInRange | array | Array de páginas devuelto por el estilo de desplazamiento |
| previous | integer | Número de la página anterior |
| totalItemCount | integer | Número total de elementos |
![[Note]](images/note.png)