分页

目录老牛浏览 10讨论 0发表于

简介

在其它框架中,分页让人很痛苦。Laravel 的分页器与 查询构造器Eloquent ORM 相结合,为数据库结果提供了开箱即用、方便易用的分页。分页器生成的 HTML 兼容 Bootstrap CSS 框架

基本使用

对查询构造器结果分页

有几种方法可以对结果分页。最简单的是在 查询构造器Eloquent 查询 上使用 paginate 方法。paginate 方法会基于用户浏览的当前页自动设置合适的数量和偏移。默认情况下,通过 HTTP 请求的 page 查询字符串参数检测当前页。当然,此值是 Laravel 自动检测的,并且还会自动插入到分页器生成的链接中。

在以下示例中,传递给 paginate 方法的唯一参数是在「每页」想要显示的数量。例如,我们想指定每页显示 15 项数据:

php
namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * 显示应用的所有用户
     *
     * @return Response
     */
    public function index()
    {
        $users = DB::table('users')->paginate(15);

        return view('user.index', ['users' => $users]);
    }
}

目前,Laravel 无法高效执行使用 groupBy 语句的分页操作。如果需要对分页的结果集使用 groupBy,建议您自己查询数据库并手动创建分页器。

「简单分页」

如果只需要在分页视图中显示简单的「上一页」和「下一页」链接,可以使用 simplePaginate 方法进行更高效的查询。对于大型数据集,如果渲染视图时不需要为每个页码都显示一个链接,此方法会非常有用:

php
$users = DB::table('users')->simplePaginate(15);

对 Eloquent 结果分页

也可以对 Eloquent 查询分页。在以下示例中,我们会对 User 模型进行分页,每页有 15 项数据。如您所见,语法与对查询构造器结果分页时一样:

php
$users = App\User::paginate(15);

当然,也可以在其它约束查询后调用 paginate,例如 where 语句:

php
$users = User::where('votes', '>', 100)->paginate(15);

对 Eloquent 模型分页时也可以使用 simplePaginate 方法:

php
$users = User::where('votes', '>', 100)->simplePaginate(15);

手动创建分页器

有时希望手动创建分页器实例,并向其传递一个项目数组。可以根据需要创建 Illuminate\Pagination\PaginatorIlluminate\Pagination\LengthAwarePaginator 实例来完成此操作。

Paginator 类不需要知道结果集中的项目总数;因此,类中也没有获取最后一页列表的方法。LengthAwarePaginatorPaginator几乎 接收相同的参数;但是,它需要结果集中的项目总数。

换句话说,Paginator 对应于查询构造器和 Eloquent 上的 simplePaginate 方法,而 LengthAwarePaginator 对应于 paginate 方法。

手动创建分页器实例时,应该手动「分割」传递到分页器的数组结果。如果不确定如何进行此操作,可以查看 PHP 函数 array_slice

显示分页结果

调用 paginate 方法时,会接收一个 Illuminate\Pagination\LengthAwarePaginator 实例。当调用 simplePaginate 方法时,会接收一个 Illuminate\Pagination\Paginator 实例。这些对象提供了几个描述结果集的方法。除了这些辅助方法外,分页器实例还是迭代器并可作为数组循环。因此,获取结果后,可以使用 Blade 显示结果并渲染页面链接:

php
<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}

links 方法会渲染结果集中剩余页面的链接。每个连接都包含合适的 page 查询字符串变量。需要记住的是,links 方法生成的 HTML 兼容 Bootstrap CSS 框架

自定义分页器 URI

withPath 方法允许您自定义生成链接时分页器所使用的 URI。例如,如果想要分页器生成像 http://example.com/custom/url?page=N 这样的链接,应该传递 custom/urlwithPath 方法:

php
Route::get('users', function () {
    $users = App\User::paginate(15);

    $users->withPath('custom/url');

    //
});

添加参数到分页链接

可以使用 appends 方法添加分页链接的查询字符串。例如,要添加 sort=votes 到每个分页链接,应调用如下 appends

php
{{ $users->appends(['sort' => 'votes'])->links() }}

如果要添加「哈希片段」到分页器的 URL,可以使用 fragment 方法。例如,要添加 #foo 到每个分页链接的最后,可以调用如下 fragment 方法:

php
{{ $users->fragment('foo')->links() }}

调整分页链接视窗

可以指定分页器每边的 URL「视窗」有多少个其它分页。默认情况下,每边的主分页器链接显示三个链接。不过,可以使用 onEachSide 方法控制此数目:

php
{{ $users->onEachSide(5)->links() }}

将结果转换为 JSON

Laravel 分页器结果类实现了 Illuminate\Contracts\Support\Jsonable 接口 Contract 并提供了 toJson 方法,因此很容易将分页结果转换为 JSON。也可以从路由或控制器操作中返回会被转换为 JSON 的分页器实例:

php
Route::get('users', function () {
    return App\User::paginate();
});

分页器的 JSON 将包含元信息,例如 totalcurrent_pagelast_page 等。实际的结果对象可以通过 JSON 数组的 data 键获取。以下是从路由中返回分页器实例创建的 JSON 的一个示例:

php
{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            // 结果对象
        },
        {
            // 结果对象
        }
   ]
}

自定义分页视图

默认情况下,渲染后显示分页链接的视图兼容 Bootstrap CSS 框架。不过,如果不使用 Bootstrap,可以自定义自己的视图来渲染这些链接。当在分页器实例上调用 links 方法时,将视图名称作为第一个参数传递给方法:

php
{{ $paginator->links('view.name') }}

// 传递数据到视图
{{ $paginator->links('view.name', ['foo' => 'bar']) }}

然而,自定义分页视图最简单的方法是使用 vendor:publish 命令将其导出到 resources/views/vendor 目录:

php
php artisan vendor:publish --tag=laravel-pagination

此命令会将视图放到 resources/views/vendor/pagination 目录。目录中的 bootstrap-4.blade.php 文件对应默认的分页视图。可以编辑该文件来修改分页 HTML。

如果要指定不同文件作为默认的分页视图,可以在 AppServiceProvider 里面使用分页器的 defaultViewdefaultSimpleView 方法:

php
use Illuminate\Pagination\Paginator;

public function boot()
{
    Paginator::defaultView('pagination::view');

    Paginator::defaultSimpleView('pagination::view');
}

分页器实例方法

每个分页器实例都通过下列方法提供额外的分页信息:

  • $results->count()

  • $results->currentPage()

  • $results->firstItem()

  • $results->hasMorePages()

  • $results->lastItem()

  • $results->lastPage() (使用简单分页时不可用)

  • $results->nextPageUrl()

  • $results->onFirstPage()

  • $results->perPage()

  • $results->previousPageUrl()

  • $results->total() (使用简单分页时不可用)

  • $results->url($page)

点赞
收藏
上一篇:查询构造器
下一篇:迁移
暂无讨论,快来发起讨论吧~
私信
老牛@ilaoniu
牛哥,俗称哞哞。单纯的九零后理工小青年。喜欢折腾,爱玩,爱安卓,爱音乐,爱游戏,爱电影,爱旅游...
最后活跃于