通用的分页模板视图/view/application/page/control.phtml:
<!--
See http://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination
-->
<?php
$url = '/application/pagination-test/test-page?page=';
?>
<?php if ($this->pageCount): ?>
<div class="paginationControl">
<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $url. $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 $url. $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 $url. $this->next; ?>">
Next >
</a>
<?php else: ?>
<span class="disabled">Next ></span>
<?php endif; ?>
</div>
<?php endif; ?>
常规的ViewModel包含模板/view/application/pagination-test/test-page.phtml:
<html>
<body>
<h1>Example</h1>
<div>
<?php if (count($this->paginator)): ?>
<ul>
<?php foreach ($this->paginator as $item):?>
<li><?php echo $item->value; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php echo $this->paginationControl($this->paginator,'Elastic','application/page/control.phtml', array('route' => 'application')); ?>
</div>
</body>
</html>
Action方法:
public function testPageAction(){
$select = new \Zend\Db\Sql\Select();
$select->from('example');
$adapterOrSqlObject = $this->getServiceLocator()->get('dbAdapter');
$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $adapterOrSqlObject);
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page'));
$paginator->setDefaultItemCountPerPage(1);
$vm = new ViewModel();
$vm->setVariable('paginator', $paginator);
return $vm;
}
以上代码分页没有任何问题。但如果我们需要让列表变成ajax加载,点击页数跳转页面无刷新效果,而不想在Js里重新很麻烦的将分页模板的逻辑及样式再写一遍, 那么我们需要共用之前的通用模板。
分页模板是通过这句代码传递参数的(如果我们AJAx方式时设置一个模板/ajax.phtml去包含这段代码将会有问题):
<?php echo $this->paginationControl($this->paginator,'Elastic','application/page/control.phtml', array('route' => 'application')); ?>
ZF2目前支持设置子模板, 但均是分开设置模板的参数的。如果Ajax方式加载时你想再通过这种方式去调用分页模板control.phtml, 那么会报找不到模板的错误, 因为这个地方分页的参数不能传递到control.phtml, 那么你可能要问为什么前面正常的情况下是能传递,并且没有问题的呢?这因为我们AJAx的action方法里需要解析模板直接返回数据给JS调用,那么加载的方式是不一样了。具体看下面的代码。
那么我们怎么解决呢?可以跳开这种思路, 有时在一个问题上纠结很久时,可以换种方法或许柳暗花明。
也许你想到了,对,我们直接调用分页模板control.phtml来进行参数赋值。
Ajax请求方法代码:
public function ajaxAction(){
$select = new \Zend\Db\Sql\Select();
$select->from('example');
$adapterOrSqlObject = $this->getServiceLocator()->get('dbAdapter');
$adapter = new \Zend\Paginator\Adapter\DbSelect($select, $adapterOrSqlObject);
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($this->params()->fromQuery('page'));
$paginator->setDefaultItemCountPerPage(1);
$renderer = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\AggregateResolver();
$map = new \Zend\View\Resolver\TemplateMapResolver(array(
'page' => __DIR__ . '/../../../view/application/page/control.phtml',
));
$resolver->attach($map);
$renderer->setResolver($resolver);
$vm = new ViewModel();
$pages = get_object_vars($paginator->getPages('Elastic'));
$vm->setTemplate('page');
if (is_array($pages)) {
$vm->setVariables($pages);
}
$pageHtml = $renderer->render($vm);
$response = $this->getResponse();
$response->setContent(json_encode(array('data'=>$paginator->getCurrentItems()->toArray(),'pageHtml'=>$pageHtml)));
return $response;
}
Ajax方式加载列表的test-page.phtml模板代码(这里是演示代码,js直接写在模板里了,正式编码放置另外单独JS文件,便于维护及缓存管理):
<html>
<body>
<h1>Example</h1>
<div class="ajaxContent">
</div>
<script>
var PageManager = {
init:function(){
this.loadDataList(1);
this.changePage();
},
changePage:function(){
var obj = this;
$('.ajaxContent').on('click','.paginationControl a',function(e){
e.preventDefault();
var href = this.href;
var ps = href.match(/page=\d+/gi);
var page = 0;
if(ps.length>0){
page = ps[0].substring(5);
}
if(page>0){
obj.loadDataList(page);
}
});
},
loadDataList:function(page){
$.ajax({
type:'GET',
url:'/application/pagination-test/ajax?page='+page,
dataType:'json',
success:function(json){
var str = '<ul>';
$.each(json.data,function(i,item){
str += '<li>'+item.value+'</li>';
});
str += '</ul>';
str += json.pageHtml;
$('.ajaxContent').html(str);
}
});
}
};
$(function(){
PageManager.init();
});
</script>
</body>
</html>