两个方向无限滚动与Firebase / Firestore后端

问题描述 投票:1回答:1

我想实现一个双向无限滚动使用Firestore作为后端,Vue.js作为前端。我不想从头开始加载完整列表,因为列表可能很大!如果我的方法一般不好,请告诉我什么是好的。

我有以下代码(只是相关部分)工作得很好:

  up() {
    console.log("up()")
    let first = this.items[0]
    console.log("first: ", first.text, first.timestamp)
    db.collection("questions").orderBy("timestamp", "desc").endAt(first.timestamp).limit(this.itemsPerPage).onSnapshot((snapshot) => {
        this.updateItems(snapshot)
    })
  },
  down() {
    console.log("down()")
    let last = this.items[this.items.length - 1]
    console.log("last: ", last.text, last.timestamp)
    db.collection("questions").orderBy("timestamp", "desc").startAt(last.timestamp).limit(this.itemsPerPage).onSnapshot((snapshot) => {
        this.updateItems(snapshot)
    })
  },
  updateItems(snapshot) {
    console.log("updateItems()")
    const temp = []
    snapshot.forEach((item) => {
      temp.push(item.data())
    })
    this.items = temp
  },
  firstLoad() {
    db.collection("questions").orderBy("timestamp", "desc").limit(this.itemsPerPage).get().then((snapshot) => {
      this.updateItems(snapshot)
    })
  }

以下是该观点的相关部分:

<p>
{{items}}
</p>
<p>
  <a href="#" @click.prevent="up">UP</a>
</p>
<ul v-for="(item, index) in items">
  <li :key="index">#{{index}} {{item}}</li>
</ul>
<p>
  <a href="#" @click.prevent="down">DOWN</a>
</p>

但我不能通过多个项目“向上移动”,因为limit()方法始终限制结果集。使用endAt()时有没有办法“反转”limit()方法?这是一个动画gif,它现在如何工作:enter image description here

不幸的是,动画gif不可见,所以这里是视频:https://youtu.be/1AR44J92Yg4

javascript firebase scroll vue.js google-cloud-firestore
1个回答
1
投票

遗憾的是,在Cloud Firestore中,没有API可以在一个范围的末尾附近获得固定数量的项目。 Firebase的实时数据库有一个limitToLast用于此目的,但Firestore上不存在该API。

您必须使用反向排序顺序创建查询,然后对其执行常规limit

db.collection("questions").orderBy("timestamp").startAt(first.timestamp).limit(this.itemsPerPage)

这意味着您将以所需的相反顺序从该查询中获取结果,因此您必须反转将它们添加到UI的方式。

对于这个特定的用例,所有这些都相当尴尬,因此我建议filing a feature request在查询中获取limitToLast方法或reverse方法。

如果您感兴趣,这是我的测试用于这些查询:https://jsbin.com/dimuvu/edit?js,output

© www.soinside.com 2019 - 2024. All rights reserved.