yii_CGridView_ajax_pagination_and_ajax_sort
本文主要内容:
1, 正常情况下 CGridView 实现 Ajax 分页和排序的原理
2, 分页和排序无法Ajax的情况分析
3, 自定义分页(重写CLinkPager)后如何实现 Ajax 分页和排序
/***
author: php攻城师
http://blog.csdn.net/phpgcs
***/
/*********** 我是分割线 *******************************/
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'keyword-grid',
'dataProvider'=>$model->search(),
'cssFile'=>false,
'template'=>'{items} <div class="page_area">{pager} {summary}</div>',
'pager'=>array('cssFile'=>false),
'ajaxUpdate'=>true,
'columns'=>array(
array(
'name'=>'leader_name',
'value'=>'$data->event',
'header'=>'关键词名称',
'headerHtmlOptions'=>array('width'=>'130px'),
), .... ....
以上代码实现一个常规的 CGridView , 除了 pager 用了自定义的样式。。
而在页面的源代码中,我来找出相关的部分:
<script type="text/javascript" src="/chuanmei/assets/f5d36ac5/jquery.ba-bbq.js"></script>
<script type="text/javascript" src="/chuanmei/assets/fb90bba/gridview/jquery.yiigridview.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
jQuery(function($) {
jQuery('#keyword-grid a.delete').live('click',function() {
if(!confirm('确定要删除这条数据吗?')) return false;
var th=this;
var afterDelete=function(){};
$.fn.yiiGridView.update('keyword-grid', {
type:'POST',
url:$(this).attr('href'),
success:function(data) {
$.fn.yiiGridView.update('keyword-grid');
afterDelete(th,true,data);
},
error:function(XHR) {
return afterDelete(th,false,XHR);
}
});
return false;
});
jQuery('#keyword-grid').yiiGridView({'ajaxUpdate':['1','keyword-grid'],'ajaxVar':'ajax','pagerClass':'pager','loadingClass':'grid-view-loading','filterClass':'filters','tableClass':'items','selectableRows':1,'pageVar':'keyword_page'});
});
/*]]>*/
</script>
其中会发现 yii 自动加载了 jquery.ba-bbq.js && jquery.yiigridview.js ,以及2段 代码
其中一段是用来实现 删除 一行数据时 弹出提示框 让用户 确认是否删除 功能 的;
一段是最核心关键的 用于 ajax update grid 的, 也正是这部分 代码 实现了 ajax 的翻页 和 排序。
/*********** 我是分割线 *******************************/
如果发现 点击了 分页 或者 排序 后,不是ajax 方式的(也就是你可以 在 地址栏 中 看到 每次 请求的常常的 url )
一个要检查的地方:
ajaxUpdate=>'', 这个参数
updateSelector=>'', 这个参数
/*********** 我是分割线 *******************************/
一般情况下,CLinkPager都无法满足我们的需求,要重写;
而重写我这里提供3种方式:
1, 禁用 CGridView自己的Pager ,在 CGridView 之外 自己写
2, 禁用 CGridView自己的Pager ,重写 CGridView 文件, 将 自己的pager 写在 public function renderItems() 中
3, 配置 CGridView 的 pager 参数。
如下是默认的 CLinkPager 的样子
翻页:
现在我们想要如下的Pager 效果
第 31 - 40 条, 共 14546 条
/***
author: php攻城师
http://blog.csdn.net/phpgcs
***/
先看第1种重写方案:
重写 CLinkpager 如下:
$this->widget('CLinkPager', array(
'header'=>'第 '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+1).
' - '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+$paginationTop->getPageSize()).
' 条, 共 '.$paginationTop->getItemCount().' 条 ',
'pages' => $paginationTop,
'itemCount'=>$totalItemFoundCount,
'prevPageLabel' => '上一页',
'cssFile'=>false,
'nextPageLabel' => '下一页',
'footer'=>' ',
));
其中的 pagination 在 controller 中生成
$paginationTop = new CPagination($totalItemFoundCount);
$paginationTop->pageSize= $pageSize;
然后把重写的 CLinkPager 放在 CGridView 前面即可。
运行后发现一个Bug ,就是 分页 不是 Ajax 的。
不是Ajax的不要紧, 关键是 分页和排序不能结合使用了。
原因很简单, 分页不是ajax 的,而排序是ajax 的, 两个 请求发出后 url 不在一个地方, 那么分页参数和 排序参数就 不再一地方, 当然无法结合使用。
解决方案: 统一起来。
要么统一为url排序&分页, 要么统一为ajax排序&分页。
url的简单, 设置 ajaxUpdate=>false,
ajax的也简单, 只要理解了本文第一部份说的 ajax 排序的原理,
之所以不能够 ajax 分页, 是因为我们的分页是 重写了, 而且还放在了CGridView 之外, 这样如何让
| jQuery('#keyword-grid').yiiGridView({'ajaxUpdate':['1','keyword-grid'],'ajaxVar':'ajax','pagerClass':'pager','loadingClass':'grid-view-loading','filterClass':'filters','tableClass':'items','selectableRows':1,'pageVar':'keyword_page'}); |
ajaxUpdate的时候 还去照顾到你写在外面的 CLinkPager 呢?
配置2个参数:
'ajaxUpdate'=>'datalist-grid, yw0',
'updateSelector'=>'.pager a, thead th a',
本来 ajaxUpdate 的作用范围 只是 datalist-gird , 现在我们告诉他 还要 作用在我们重写在grid 外面的 分页 ul ,其id 是 yw0.
updateSelector 指定了 触发 ajaxUpdate 这个动作的html元素, 也是要保证 包含了 分页的链接和排序的链接 , 否则也是无法成功 ajax 排序/分页。
再看第2种重写方案:
上面第一种方案 太复杂了把, 既然问题的核心关键是 没有把自定义的 ClinkPager 放在 CGridView 中, 那我们就重写 CGridView将其放进去呗。
对,确实是可行的。
<?php
Yii::import('zii.widgets.grid.CGridView'); class EbuCGridView extends CGridView
{
/**
* Renders the data items for the grid view.
*/
public function renderItems()
{
if($this->dataProvider->getItemCount()>0 || $this->showTableOnEmpty)
{
$this->renderCustomerPager();
echo "<table class=\"{$this->itemsCssClass}\">\n";
$this->renderTableHeader();
ob_start();
$this->renderTableBody();
$body=ob_get_clean();
$this->renderTableFooter();
echo $body; // TFOOT must appear before TBODY according to the standard.
echo "</table>";
$this->renderCustomerPager();
}
else
$this->renderEmptyText();
} public $paginationTop;
public $totalItemCount;
public $totalItemFoundCount;
public function renderCustomerPager()
{
$paginationTop = $this->paginationTop;
$totalItemCount = $this->totalItemCount;
$totalItemFoundCount = $this->totalItemFoundCount;
echo '<div class="page_area" style="text-align:right;">';
echo '<div class="pager">';
$this->widget('CLinkPager', array(
'header'=>'第 '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+1).
' - '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+$paginationTop->getPageSize()).
' 条, 共 '.$paginationTop->getItemCount().' 条 ',
'pages' => $paginationTop,
'itemCount'=>$totalItemFoundCount,
'prevPageLabel' => '上一页',
'cssFile'=>false,
'nextPageLabel' => '下一页',
'footer'=>' ',
));
....
前2种方案,说实话,都太麻烦了,破坏了yii 自身的机制, 又在其上弥补了半天。。
最好的方案 ,还是 配置 CGridView 的 'pager' ,来实现我们要更复杂的CLinkPager的目标。
但是,有些时候还真必须用第 1、2种方案;
比如我应用的情况是:
用 Coreseek 全文索引 查询出 数据 的id ,再 用 id 来到数据库中找出数据,形成 CActiveDataProvider ,最后用 CGridView来展示。
我这里的 CDbCriteria 如下
$criteria = new CDbCriteria;
$criteria->join = 'LEFT JOIN site2 AS si** ON t.**=**.domain_hash';
$criteria->addInCondition('t.id', $IDARRAY);
$criteria->select = array("t.id", "t.content", "t.pubtime", "t.url", "t.reply_num", "t.retweet_num", "site_config.site_name");
$criteria->order = 'FIND_IN_SET(t.id, "'.join(",", $IDARRAY).'")';
其中 变量 IDARRAY 正是 coreseek 得到的 一个 id 组成的数组
如果按照 普通的
$dataProvider = new CActiveDataProvider('TData', array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>10,
),
));
是不满足我的需求的。
因为我的分页和排序都是在 coreseek 中完成的, 这里用 CActiveDataProvider 只是提供了当前页(比如每一页10条记录)的10条记录。
end。
有更好的建议和意见,欢迎提出共同学习。
yii_CGridView_ajax_pagination_and_ajax_sort的更多相关文章
随机推荐
- eclipse序列化生成serialVersionUID
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 如果你修改代码重新部署后出现序列化错误,可以考虑给相应的类增加serialVersio ...
- Android RelativeLayout常用属性介绍
下面介绍一下RelativeLayout用到的一些重要的属性: 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layou ...
- 让2个并列的div根据内容自动保持同等高度js
有左右2个并列的div,2个div都不能限定高度.左div为导航,右div为内容.如何能让左div块自动获得和右div块相等的高度? 同时,也有网友提问到“如果右块高度比左块低,会不会导致左块的内容被 ...
- raphael 支持group(简)
raphael 不支持group,里面有的set方法,只是把对象数组存起来,方法调用的时候,遍历都调用下,但是在实际需求上面感觉group还是瞒有用处的,可以控制group下面的节点的交互 比如地图区 ...
- PHP_OOP
1.存储器方法——用于限制对象的变量属性 对于弱类型的PHP,存储器方法来限制变量属性显得非常重要! 通过为所有属性创建存储器方法,可以简化添加数据验证或新的业务逻辑的工作,也可以简化在后边对对象执行 ...
- Oratop工具——实时数据库性能监控工具
在任何系统优化过程中,“80/20原则”是我们一定要关注的问题.简单的说,就是我们系统80%的性能问题.现象,都是有少数几个甚至一个问题造成的.这就需要我们面对复杂的系统性能问题的时候,要学会“拨开云 ...
- JavaMail学习笔记
适逢计算机网络课程设计,本着挑战自己的态度,选择了一个从未接触的东西:邮箱客户端代理软件的设计.由于对相关协议非常陌生,只能依靠查找资料完成,在学习过程中碰到了一个非常好的博客,故向大家推荐一下. 一 ...
- 关于android:screenOrientation="portrait" 横竖屏切换
当在AndroidManifest.xml文件中定义了android:screenOrientation="portrait",就表示当我们切换横竖屏的时候,屏幕的内容始终以竖屏显 ...
- RDIFramework.NET(.NET快速信息化系统开发框架) Web版介绍
RDIFramework.NET(.NET快速信息化系统开发框架) Web版介绍 B/S结构(Browser/Server,浏览器/服务器模式),是WEB兴起后的一种网络结构模式,WEB浏览器是客户 ...
- ubuntu系统安装FTP
Ubuntu安装vsftp软件 1.更新软件源 首先须要更新系统的软件源,便捷工具下载地址:http://help.aliyun.com/manual?spm=0.0.0.0.zJ3dBU&h ...