【问题标题】:How to "go back" on paginated items如何“返回”分页项目
【发布时间】:2019-11-27 21:24:21
【问题描述】:

我有一个简单的集合,我想分页。 我想通过一个名为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()
      }))
    }
  }
}

就目前而言,我的 Firestore 中总共有 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>
    )  
  }
)


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

【问题讨论】:

  • 你到底是如何向前翻页的?您显示的是第一个查询,而不是您如何进行后续查询。
  • @DougStevenson 我进行了编辑,显示了代码并给出了简要说明。
  • 简要看...我认为 limit 可以采用多个参数(查看文档)。通常你可以传递一个startstop 集合或limitstart 集合。您的第一个起点可能是 0,3,第二个可能是 3,6(这可能因实施而异)。通过你要去的分页页面并计算你开始停止
  • endBefore 对您有用吗?它在文档中有所描述。

标签: javascript firebase google-cloud-firestore


【解决方案1】:

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

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

【讨论】:

  • 明确地说,我的数据集不会保持那么小。我只是为了示例而提出它。理想情况下,我希望只使用startAtendAt 并传入任何索引,但这不起作用。不管数字多少,我总是得到相同的条目,所以我猜这也不正确?
  • 在定期添加和删除项目时,跟踪哪个元素是哪个页面的第一个是不可能的。如果我能把它变成一个数字,那就太理想了。
  • 如果项目在整个查询中不断移动,那么分页根本不会对您有太大帮助。在这种情况下,您需要的是一个带有快照观察者的单个实时查询,只要查询结果发生变化,它就会给您一个回调。但是,在这种情况下没有可用的分页。您必须选择 - 当结果随时间变化时您想要实时查询结果,还是想要分页?你不能同时拥有两者。
  • 这里的目标只是显示一小部分数据(我的结果),而不是一个巨大的列表。对于这个例子,我想同时带入 3 个项目,然后当用户单击 Next 时,他们会得到接下来的三个。数据偶尔会发生变化,但不会到用户会在屏幕上看到它发生变化的程度,它已经足够了,我不能指望一个项目总是在同一页面上。
  • 同样,分页对您的帮助不大,因为您的页面会随着时间的推移而变化,并且数据项可能会被跳过或重复,具体取决于何时发生的情况。你需要一些稳定的东西才能使分页有意义。
猜你喜欢
  • 2017-05-11
  • 1970-01-01
  • 2017-06-05
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 1970-01-01
  • 2021-02-01
相关资源
最近更新 更多