关于tp5的paginate方法,我查找了一些文档,没有去讲它的原理是什么样的,我们来分析一下这个方法会做什么
1.控制器中添加入口
首先,我们会在我们的控制器中添加入口,如下 :
public function index(){
$result = model("News")->order(['id'=>'asc'])->paginate();
$this->assign('list',$result);
return $this->fetch() ;
}
它做了什么呢?
它查找news这个库中id正序数据,这个paginate()方法,其实类似于select()方法,执行完之后,它都会执行查询操作,然后返回数据。
2.在html中渲染数据
查询完之后,我们把数据 assign到了模板中,我们看一下我们模板中的使用。
{volist name='list' id='vo'}
<tr class="text-c">
<td><input type="checkbox" value="" name=""></td>
<td>{$vo.id}</td>
<td class="text-l"><u style="cursor:pointer" class="text-primary" title="查看">{$vo.title}</u></td>
<td>{$vo.catid}</td>
<td><img width="60" height="60" class="picture-thumb" src="{$vo.image}"></td>
<td>{$vo.update_time}</td>
<td>{$vo.is_position}</td>
<!-- 略-->
{/volist}
我们通过{volist}标签,把数据渲染到界面上,其实这步和paginate关系不太大,这个只是一个步骤。
3.添加分页的标签(重点)
下面就该我们添加分页的标签了
{volist name='list' id='vo'}
<!-- 略-->
{/volist}
</tbody>
</table>
<div id="laypage"></div>
</div>
</div>
{:pagination($list)}
核代码:{:pagination($list)}
这是一个分页实现的核心实现,它是一个php的方法,我们把它写在了通用的方法common.php中,我们来看一下。
function pagination($obj){
if(!$obj){
return '' ;
}
$params = request()->param();
return '<div class="imooc-app">'.$obj->appends($params)->render().'</div>';
}
执行了这段代码,会发生什么呢?这段代码会生成一段如下的代码,我们来看看。
<div class="imooc-app">
<ul class="pagination">
<li><a href="/admin/news/index.html?page=3">«</a></li>
<li><a href="/admin/news/index.html?page=1">1</a></li>
<li><a href="/admin/news/index.html?page=2">2</a></li>
<li><a href="/admin/news/index.html?page=3">3</a></li>
<li class="active"><span>4</span></li><li><a href="/admin/news/index.html?page=5">5</a></li>
<li><a href="/admin/news/index.html?page=6">6</a></li>
<li><a href="/admin/news/index.html?page=7">7</a></li>
<li><a href="/admin/news/index.html?page=5">»</a></li>
</ul>
</div>
这样我们就不难分析出来了。
<div class="imooc-app"></div>这段是我们在pagination()方法里拼的,所以render()方法会生成<ul><li>...</li></ui>这一段代码。
我们来看看这段代码生成的url:/admin/news/index.html?page=3
清楚地看到,这个都是带参数的。
这就是为什么appends方法需要request()->param()方法了,它是会把请求里的参数传过来,生成这个参数的。
流程是这样的:
首先我们第一次请求php的paginate();方法,
result,注意result的结构
{"total":31,"per_page":5,"current_page":1,"last_page":7,"data":[]}
它带了分页数据,总条数,每页的条数,当前多少页,最后一页。
这个$result会被分配到模板中
模板中会调用我们common.php中的方法,根据这个结果json,判断一共多少页,于是生成多少个<li>并且在url中添加了page=N
但是注意上面有一个疑惑点:
明明通过php的paginate();方法,查出来的数据是一个object,但是在前端界面中就可以直接使用循环数据,what?我们做了如下的打印。
{:dump(json_encode($list))}
{:dump(json_encode($vo))}
打印出来确实是直接给我们转化好了。我们来看一下
//list数据,看到是带data的一个object
{"total":31,"per_page":5,"current_page":1,"last_page":7,"data":[{"id":1,"title":"\u6d4b\u8bd5\u6587\u7ae0","small_title":...
//vo数据,已经帮我们解析成了对象,并没有因为list是一个object而出现问题,所以在这个{volist}标签内部肯定给我们做了处理
{"id":1,"title":"\u6d4b\u8bd5\u6587\u7ae0","small_title":"aaaa","catid":0,"image":"\/uploads\/20200321\/b53c3d8180c149b2b8fe7bda2e89e2e7.png"...
同样的,我们看一个volist的代码,确实做了处理
没有具体的去细读,但是浏览一下,也能看到它对数组和非数组的处理了。
public function tagVolist($tag, $content)
{
$name = $tag['name'];
$id = $tag['id'];
$empty = isset($tag['empty']) ? $tag['empty'] : '';
$key = !empty($tag['key']) ? $tag['key'] : 'i';
$mod = isset($tag['mod']) ? $tag['mod'] : '2';
$offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;
$length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';
// 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist>
$parseStr = '<?php ';
$flag = substr($name, 0, 1);
if (':' == $flag) {
$name = $this->autoBuildVar($name);
$parseStr .= '$_result=' . $name . ';';
$name = '$_result';
} else {
$name = $this->autoBuildVar($name);
}
$parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): $' . $key . ' = 0;';
// 设置了输出数组长度
if (0 != $offset || 'null' != $length) {
$parseStr .= '$__LIST__ = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); ';
} else {
$parseStr .= ' $__LIST__ = ' . $name . ';';
}
$parseStr .= 'if( count($__LIST__)==0 ) : echo "' . $empty . '" ;';
$parseStr .= 'else: ';
$parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): ';
$parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );';
$parseStr .= '++$' . $key . ';?>';
$parseStr .= $content;
$parseStr .= '<?php endforeach; endif; else: echo "' . $empty . '" ;endif; ?>';
if (!empty($parseStr)) {
return $parseStr;
}
return;
}
网友评论