使用Firebase实现无限滚动?

6
      var self = this;
      var firebaseRef = new Firebase(baseUrl + '/sparks');

      firebaseRef.limitToLast(5).on('child_added', function(childSnapshot, prevChildKey) {
        self.addChild(childSnapshot); // adds post to a <div>
      });

数据库布局

我的代码目前加载了最近的5篇文章,并将加载任何新文章。但是,我也想能够加载旧文章。我有一个按钮,当点击时将调用一个函数(我不确定如何实现),以加载旧文章。我该如何检索这些旧文章?

(箭头只是表示我想从底部开始检索文章,逐步向上)


__firebaseKey__是什么?你能在像jsfiddle/jsbin这样的网站上设置一个可重现的示例吗? - Frank van Puffelen
@FrankvanPuffelen 我更新了我的帖子。希望现在更清楚我的目标是什么。 - Chris W
2个回答

13

你需要反向思考才能完成这个任务。当你获得第一页的查询结果时,请记住结果中的第一个项目:

firebaseRef.endAt().limitToLast(5).on('child_added', function(childSnapshot, prevChildKey) {
    self.addChild(childSnapshot); // adds post to a <div>
  });

虽然在Firebase中无法通过索引访问子项,但您可以存储项目的键并使用它来开始下一个查询。

var firstKnownKey;
firebaseRef.orderByKey().limitToLast(5).on('child_added', function(childSnapshot, prevChildKey) {
    if (!firstKnownKey) {
      firstKnownKey = childSnapshot.key;
    }
    self.addChild(childSnapshot); // adds post to a <div>
});

现在你有一个名为firstKnownKey的变量,该变量存储了你曾经看到的第一个键。要获取先前的一批子节点,当你发出下一个查询时,将该值传递给endAt()

firebaseRef.orderByKey().endAt(firstKnownKey).limitToLast(5).on('child_added', function(childSnapshot, prevChildKey) {
    if (!firstKnownKey) {
      firstKnownKey = childSnapshot.key;
    }
    self.addChild(childSnapshot); // adds post to a <div>
});

最近几天类似问题的答案:


谢谢,这正是我所需要的。我的问题在于没有使用orderByKey(),使用了startAt而不是EndAt以及limitToFirst而不是limitToLast! - Chris W
@Frank,你的第三段代码每次都会返回相同的结果,因为 firstKnownKey 的值与获取第一批数据时的一样。 - Silviu
你需要为每个加载的页面更新 firstKnownKey - Frank van Puffelen
1
我已经花了8个多小时来让这个工作正常运行。你能否给我们提供一个更详细的示例呢? 我有这个:https://i.imgur.com/7WTWxYu.png 第一批处理得很好,但之后我会收到重复的结果集,我不知道该如何解决。 谢谢! - Silviu
1
@FinPercy 请在编辑时使用 <!----> 来避免 6 个字符的限制。 - Donald Duck

1

由于 endAt() 是包含在内的,所以每次执行无限滚动时,最后一个项目会重复出现,因此我对frank van puffen的答案进行了一些修改。

我初始化了一个列表childrenVal来存储所有的值,另一个列表childrenKey来存储所有的键,和一个变量firstKnownKey,正如frank van puffen所建议的那样。

var childrenVal=[];
var childrenKey=[];
var firstKnownKey = "";

当您第一次进行查询时,您将获得最后5个元素:

getFirst(){
    firebaseRef.orderByKey().limitToLast(5).once('value')
        .then((snap)=>{
            snap.forEach(childSnap => {
                childrenVal.unshift(childSnap.val());
                childrenKey.unshift(childSnap.key);
            });
            firstKnownKey = childrenKey[childrenKey.length-1];
        });
}

在您的下一个查询中,您不希望重复使用您的firstKnownKey,因此我编写了以下函数:
exclude(key){
    return key.substring(0, key.length - 1) + String.fromCharCode(key.charCodeAt(key.length - 1) - 1)
}

对于查询本身,以下函数:

getNext() {
    firebaseRef.orderByKey().endAt(exclude(firstKnownKey)).limitToLast(5).once('value')
        .then((snap) => {
            snap.forEach(childSnap => {
                childrenVal.unshift(childSnap.val());
                childrenKey.unshift(childSnap.key);
            });
            firstKnownKey = childrenKey[childrenKey.length - 1];
        });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接