首页 > 解决方案 > 如何“返回”分页项目

问题描述

我有一个简单的集合,我想分页。我想对它进行排序并通过一个名为createdAt.

这是当前调用的样子:

function getPaginatedItems (db, startAfter) {
  return db
    .collection('items')
    .orderBy('createdAt')
    .startAfter(startAfter) // startAfter parameter will be a createdAt Timestamp doc
    .limit(3)
    .get()
}

为了使它更易于使用和显示,我创建了一个函数,将这个查询快照转换为一个分页对象。这看起来像这样:

function querySnapshotToPaginatedObject (querySnapshot, total, limit = 3) {   if (querySnapshot.empty) {
    return {
      total: 0,
      limit,
      data: []
    }
  } else {
    return {
      total,
      limit,
      data: querySnapshot.docs.map(doc => ({
        id: doc.id,
        ...doc.data()
      }))
    }
  }
}

就目前而言,我的火库里总共有 11 件物品,但我想把它们分成三块。当处理数据时,这一切都完美无缺,但是我的问题变成了,我该如何回去?也就是说,我如何从以前的页面中获取数据?

目前我手中的东西是我拥有的项目总数,可以显示的限制,显然我目前正在显示的三个项目。

我不知道如何跟踪所有其他页面以便跳回页面,或者为此跳转超过一页。

所以我想这里有两个问题:我如何回到以前的数据?我怎么能跳转不同的数据块?

还有另一种方法可以做到这一点,也许是通过索引而不是特定的文档(就像我对 createdAt 所做的那样)?

编辑:有人问我如何进行下一个查询。基本上我有按钮(都带有页码),当我点击它们时,我会从createdAt最后一项的属性开始进行第二次调用。然后我对我的初始查询进行第二次调用,但将最后一个对象作为函数调用startAfter中的参数传递。getPaginatedItems

我使用 react 作为前端,所以它看起来像这样:

getNextBatch (startAfter) {
  return { 
    paginatedItems: querySnapshotToPaginatedObject(
      await getPaginatedItems(db, startAfter), 11, 3
    )
  } 
}

...
export default class MyComponent extends React.Component (
  render () {
    return (
      <div>
        {this.props.paginatedItem.map(x => <div>{x.name} {x.createdAt}</div>)}

        <button onClick={(evt) => console.warn('How do I go back???')}>
          Back
        </button>
        <button onClick={(evt) => getNextBatch(paginatedItem[paginatedItem - 1].createdAt)}>
          Next
        </button>
      </div>
    )  
  }
)


请记住,每次单击按钮时组件都会重新渲染。

标签: javascriptfirebasegoogle-cloud-firestore

解决方案


Cloud Firestore API 不提供向后翻页的方法。在您的情况下,最简单的方法是记住startAfter您用来获取每个页面的值列表。每个值将代表一页数据。这样,返回上一页只需startAfter从该列表中找到所需的值,然后使用该值进行查询。

不过,老实说,您的总数据集非常小,可能根本不值得分页。我只是得到整个事情并记住它。在您达到数百或数千个文档之前,分页可能不会变得有价值(当然,这取决于每个文档有多大,以及您希望有多少可用内存)。


推荐阅读