很早就想记录一下,但是直到今天才有时间,目的就是希望大家可以避坑,下面进入正文
默认使用model方法paginate作为分页,其实laravel 里面已经做了很多处理,作为开发者来讲其实就想简简单单的调方法而已,但是事与愿违,总会有特殊的定制,下面就来讲讲怎么定义不一样的html
找到模版
找到Illuminate\Database\Eloquent\Builder.php类中的对应方法,实际上实例化的是LengthAwarePaginator这个类,传入了一些基本分页信息,
再根据namespace继续追代码 Illuminate\Pagination\LengthAwarePaginator想到在视图中使用render 来渲染html代码,则观察下面方法public function render(Presenter $presenter = null) { if (is_null($presenter) && static::$presenterResolver) { $presenter = call_user_func(static::$presenterResolver, $this); } $presenter = $presenter ?: new BootstrapThreePresenter($this); return $presenter->render(); }
看后面的代码可以知道这个Presenter 其实就是一个模版对象,这里暂且这样理解
创建自己的模版
下面有几个坑要注意
下面都以BootstrapThreePresenter举例
继承PresenterContract
\Illuminate\Contracts\Pagination\Presenter
观察 LengthAwarePaginator 类的同级目录下会发现好多个Presenter的类,我们打开 BootstrapThreePresenter 这个类就会发现继承了上面的这个Presenter接口,因为在其他的地方会有类型约束,也为了和laravel本身框架的代码风格保持一致,所以后面我们定义的模版也继承就可以了
生成html结构
恶心的地方来了。。。
这里引入了traits所以结构有些混乱,你别看定义了好几个方法,但是protected全tm在traits里面调用,我们看最主要的渲染方法public function render(){ if ($this->hasPages()) { return sprintf( '
- %s %s %s
如果你还需要增加首页或者末页,只需要在<ul class="pagination">%s %s %s</ul>
里面额外定义字符串参数就可以了
调用与封装
接下来我把项目中现成的代码拷贝过来
调用的封装
/** * * @return string 分页Html代码 */function pagination(\Illuminate\Contracts\Pagination\Paginator $paginator, $template = 'simple'){ //这里我定义了多个模版所以做了点处理 $class = '\App\Libraries\Common\Pagination\\'.ucfirst($template).'Presenter'; $paginator->setPath(request()->url()); return $paginator ->appends(request()->input()) ->render(new $class($paginator)); //实例化把自己传进去 我觉得恶心的不行,感觉像自己日自己}//demo$paginate = User::paginate();pagination($paginate, 'ajax');
SimplePresenter.php
paginator = $paginator; $this->window = is_null($window) ? UrlWindow::make($paginator) : $window->get(); } /** * Determine if the underlying paginator being presented has pages to show. * * @return bool */ public function hasPages() { return $this->paginator->hasPages(); } /** * Convert the URL window into Bootstrap HTML. * * @return string */ public function render() { if ($this->hasPages()) { return sprintf( '%s %s %s %s %s', $this->getLinks(), $this->getFirstButton('首页'), $this->getPreviousButton('上一页'), $this->getNextButton('下一页'), $this->getLastButton('末页') ); } return ''; } /** * Get HTML wrapper for an available page link. * * @param string $url * @param int $page * @param string|null $rel * @return string */ protected function getAvailablePageWrapper($url, $page, $rel = null) { $rel = is_null($rel) ? '' : ' rel="'.$rel.'"'; return ''.$page.''; } /** * Get HTML wrapper for disabled text. * * @param string $text * @return string */ protected function getDisabledTextWrapper($text) { return ''.$text.''; } /** * Get HTML wrapper for active text. * * @param string $text * @return string */ protected function getActivePageWrapper($text) { return ''.$text.''; } /** * Get a pagination "dot" element. * * @return string */ protected function getDots() { return $this->getDisabledTextWrapper('...'); } /** * Get the current page from the paginator. * * @return int */ protected function currentPage() { return $this->paginator->currentPage(); } /** * Get the last page from the paginator. * * @return int */ protected function lastPage() { return $this->paginator->lastPage(); } }
我的方式可能不是最优雅的,也可能会有其他方法,但是我这里只介绍一个思路,不做其他尝试