分页

未匹配的标注

Lucid 内置了对 基于偏移分页 的支持。您可以通过 .paginate 方法对查询结果进行分页。

paginate 方法接受页码作为第一个参数,将要获取的行作为第二个参数。在内部,我们执行一个额外的查询来计算总行数。

const page = request.input('page', 1)
const limit = 10

const posts = await Database.from('posts').paginate(page, limit)
console.log(posts)

paginate 方法返回 SimplePaginatorClass 的实例。它保存分页的元数据,以及获取的 rows

SimplePaginator {
  perPage: 10,
  currentPage: 1,
  firstPage: 1,
  isEmpty: false,
  total: 50,
  hasTotal: true,
  lastPage: 5,
  hasMorePages: true,
  hasPages: true
}

显示分页链接

以下是在 Edge 模板中显示分页链接的完整示例。

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Database from '@ioc:Adonis/Lucid/Database'

class PostsController {
  public async index ({ request, view }: HttpContextContract) {
    const page = request.input('page', 1)
    const limit = 10

    const posts = await Database.from('posts').paginate(page, limit)

    // 更改分页链接的 baseURL
    posts.baseUrl('/posts')

    return view.render('posts/index', { posts })
  }
}

打开 posts/index.edge 文件并将以下代码片段粘贴到其中。

<div>
  @each(post in posts)
    <h1>{{ post.title }}</h1>
    <p> {{ excerpt(post.body, 200) }} </p>
  @endeach
</div>

<hr>

// 高亮开始
<div>
  @each(anchor in posts.getUrlsForRange(1, posts.lastPage))
    <a href="{{ anchor.url }}">
      {{ anchor.page }}
    </a>
  @endeach
</div>
// 高亮结束

getUrlsForRange 方法接受一系列页面并返回具有以下属性的对象数组。

[
  {
    url: '/?page=1',
    page: 1,
    isActive: true,
    isSeperator: false,
  },
  {
    url: '/?page=2',
    page: 2,
    isActive: true,
    isSeperator: false,
  },
  // ...
]

序列化为 JSON

您还可以通过调用 toJSON 方法将分页器结果序列化为 JSON。它默认返回 snake_case 中的键名。但是,您可以通过 命名策略 来覆盖默认约定。

const posts = await Database.from('posts').paginate(page, limit)
return posts.toJSON()
{
  "meta": {
    "total": 50,
    "per_page": 5,
    "current_page": 1,
    "last_page": 10,
    "first_page": 1,
    "first_page_url": "/?page=1",
    "last_page_url": "/?page=10",
    "next_page_url": "/?page=2",
    "previous_page_url": null
  },
  "data": []
}

在下面的示例中,我们覆盖命名策略以返回 camelCase 中的键。

const posts = await Database.from('posts').paginate(page, limit)

posts.namingStrategy = {
  paginationMetaKeys() {
    return {
      total: 'total',
      perPage: 'perPage',
      currentPage: 'currentPage',
      lastPage: 'lastPage',
      firstPage: 'firstPage',
      firstPageUrl: 'firstPageUrl',
      lastPageUrl: 'lastPageUrl',
      nextPageUrl: 'nextPageUrl',
      previousPageUrl: 'previousPageUrl',
    }
  }
}

return posts.toJSON()

您还可以为 SimplePaginator 类构造函数分配自定义命名策略以全局覆盖它。以下代码必须进入提供程序或 预加载文件

import { ApplicationContract } from '@ioc:Adonis/Core/Application'

export default class AppProvider {
  constructor(protected app: ApplicationContract) {}

  public async ready() {
    // 高亮开始
    const Db = this.app.container.use('Adonis/Lucid/Database')

    Db.SimplePaginator.namingStrategy = {
      paginationMetaKeys() {
        return {
          // ... 同上
        }
      }
    }
    // 高亮结束
  }
}

补充阅读

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/da...

译文地址:https://learnku.com/docs/adonisjs/5.x/da...

上一篇 下一篇
贡献者:2
讨论数量: 0
发起讨论 只看当前版本


暂无话题~