Laravel5.1 自定义分页样式的探索

本分同步发表自:http://www.h57.pw/aritlce/19

话说,自己在写这个博客的时候要弄到分页,按照文档 rander() 出来以后居然是bootstrap的样式,这是什么鬼。百度了一圈之后,很多文章都是说改源码,这一定不科学。对于框架来说一定是可以扩展的,所以,开始爬源码吧。当我们调用 paginate() 方法的时候返回的是一个 \Illuminate\Contracts\Pagination\LengthAwarePaginator 实例,不过这个东西是个接口,肯定会有实现类的,所以,继续查,发现了 Illuminate\Pagination\LengthAwarePaginator 这个类实现了上边的接口,好吧,就决定是你了,皮卡丘。

继续看 render 方法

    /**
     * Render the paginator using the given presenter.
     *
     * @param  \Illuminate\Contracts\Pagination\Presenter|null  $presenter
     * @return string
     */
    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();
    }

上面的最终返回了一个BootstrapThreePresenter,进去看一下,发现就是渲染分页样式的,所以说,我们只要自己定义一个分页样式类,并且传入render方法,就可以了。

下面我们自定义一个 AmazeuiThreePresenter 类,继承自BootstrapThreePresenter,因为这样就可以节省好多方法了。
下面上最终代码

<?php

namespace App;

/**
 * Created by PhpStorm.
 * User: Chris
 * Date: 2016/8/21
 * Time: 20:34.
 */
class AmazeuiThreePresenter extends \Illuminate\Pagination\BootstrapThreePresenter
{
    public function render()
    {
        if ($this->hasPages()) {
            return sprintf(
                '<ul class="am-pagination am-pagination-centered">%s %s %s</ul>',
                $this->getPreviousButton(),
                $this->getLinks(),
                $this->getNextButton()
            );
        }

        return '';
    }

    /**
     * Get HTML wrapper for disabled text.
     *
     * @param string $text
     *
     * @return string
     */
    protected function getDisabledTextWrapper($text)
    {
        return '<li class="am-disabled"><span>'.$text.'</span></li>';
    }

    /**
     * Get HTML wrapper for active text.
     *
     * @param string $text
     *
     * @return string
     */
    protected function getActivePageWrapper($text)
    {
        return '<li class="am-active"><span>'.$text.'</span></li>';
    }
}

这样就ok了,好多方法 BootstrapThreePresenter 都实现出来了,所以我们只要修改一些对于我们样式相关的就可以了。

最后,我们在模板render的时候传入我们自定义的就可以了。如下

 {!! $articles->render(new \App\AmazeuiThreePresenter($articles)) !!}

最后的最后,再写这个文章的时候,发现了 static::$presenterResolver 这个东西,是不是还有更简单的方法呢,待我研究研究

本帖已被设为精华帖!
本帖由 Summer 于 8年前 加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 11

SOLID 的理论中 里氏替换原则 就是说“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”,你这个就是一个很好的例子

8年前 评论

5.3 和5.1的代码似乎不一样了。不过也也好理解,因为5.3已经允许自定义分页样式了。

8年前 评论

https://github.com/sinoci/sinoci/blob/mast...
可以看下这个,是用传闭包给 Paginator::presenter 来实现的

8年前 评论
chongyi
8年前 评论

这个不需要继承,你实现借口就好了。

use Illuminate\Contracts\Pagination\Presenter as PresenterContract;

就是上面的接口。
服务提供者里面这么写

Paginator::presenter(function($app){
//          dd($app);
            return new DiyPaginationPresenter($app);

       });

在服务提供者里面写个闭包。

8年前 评论

@bluegeek 错别字好尴尬。。。。

8年前 评论

@bluegeek 感谢,继承过来的想法是,那个类已经实现了很多的方法了,然后我只需要修改一下需要覆盖的方法就可以了,主要是懒。在我新的代码里面已经采用下面的方法了,不过我有一个问题,那个匿名函数的参数列表我应该到哪里去查看的。

8年前 评论

@M1racle 你都看过源代码了,那么你应该可以找到这样的写法,我就不给你贴laravel的代码了。

class TestClosure
{

    public function test(Closure $func)
    {
        call_user_func($func, $this);
    }
}

测试代码

// $test->test();报严重错误

$test->test(function () {
    echo "This a test";
});//打印成功This a test

$test->test(function ($a) {
    print_r($a);
});//打印成功

结果是这样的。

This a testTestClosure Object
(
)

由上面的的例子可以知道,当类的方法中传入了闭包对象作为参数,参数是任意的,也就是说你完全可以传入任意数量的参数,但是call_user_func要和闭包的参数数量一致,不然会有警告。call_user_func($func, $this),这里$this是参数,只有一个参数$test->test(function ($a) {
print_r($a);
});也就只能这么写,当然不传参数也是可以的。这里比call_user_func($func, $this)的参数只能少不能多。

回到laravel中就是,

  • Illuminate\Pagination\AbstractPaginator
    public static function presenter(Closure $resolver)
    {
        static::$presenterResolver = $resolver;
    }
  • Illuminate\Pagination\Paginator和Illuminate\Pagination\LengthAwarePaginator

    public function render(Presenter $presenter = null)
    {
        if (is_null($presenter) && static::$presenterResolver) {
            $presenter = call_user_func(static::$presenterResolver, $this);
        }
    
        $presenter = $presenter ?: new SimpleBootstrapThreePresenter($this);
    
        return $presenter->render();
    }

    $presenter = call_user_func(static::$presenterResolver, $this);

所以匿名函数的参数列表就参照call_user_func调用就可以了。

请参照。

8年前 评论

@bluegeek 多谢解释,是我想跑偏,非常感谢

8年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!