使用 AngularFire2 分页

Pagination using AngularFire2

我正在构建一个使用 Firebase 的 Ionic2 项目,我正在使用 AngularFire2。

从 AngularFire2 文档中,我能够得到类似的东西:

const queryObservable = af.database.list('/items', {
  query: {
    orderByChild: 'size',
    equalTo: subject 
  }
});

这很好用。我有大约 300-400 条记录,但我无法在一个 API 调用中全部提取。所以我正在尝试实现分页。我尝试了很多东西。我要实现的是 this:

StartAt(), endAt()

我试图通过查询对象传递它,但没有成功。 AngularFire2 有这方面的实现吗? 如果没有,我如何获得 Firebase ref 以便我可以编写自己的实现?

AngularFire2 根据 source code 支持 startAtendAt。以下是如何根据子键为 size:

的列表限制查询
let queryObservable = this.af.database.list('/items', {
  query: {
    orderByChild: 'size',
    startAt: 50,
    endAt: 100
  }
});

这应该拉取所有子键 size 定义在 50 到 100 之间的项目。

NOTE 我注意到如果我将引用对象而不是引用路径传递给 AngularFire2,查询将 NOT 工作!所以下面的代码仍然会 return 项目列表,但不会正确排序。

let ref = firebase.database().ref('/items');
this.af.database(ref, { query: { orderByChild: 'size' } });

我最近在 blog post 中查看了这个问题,但您提出了一个有趣的边缘案例,您的总查询将比您想要提取的要大。我将使用与以前相同的方法解决此问题,但实施开始于和结束于而不是 limitToLast。此外,您使用从 rxjs 导入的 BehaviorSubjects,因为它们将允许您获取当前值并增加一定数量。例子

let firstKey = new BehaviorSubject(''); // import 'rxjs/BehaviorSubject'
let nextKey = new BehaviorSubject('');
let pageSize = new BehaviorSubject(10);

let queryObservable = this.af.database.list('/items', {
 query: {
   orderByKey: true,
   startAt: firstKey,
   limitToFirst: pageSize
 }
});

现在您有一个不断移动的 window 从第一个键开始并使用这些键作为您排序的值。例如,为了能够更改密钥,您需要将所需的密钥存储在特定位置。

queryObservable.subscribe((data) => {
    // angularfire2 adds a $key property to each result in an array
    // Does not handle the edge case at the end of the list
  if (data.length === pageSize.getValue()) {
    nextKey.next(data.$key);
  }
});

要增加和减少window,只需将firstKey值更改为nextKey的值即可。

firstKey.next(nextKey.getValue());

您可以做各种巧妙的事情,例如添加多个页面,或者通过对这种方法进行微调后返回一个页面。这与添加您必须在数据库中维护的字段相反,后者在某些情况下可能很麻烦。

我还需要使用 Angular 2 和 Firebase 进行简单的分页(下一页和上一页)。

我的解决方案是从列表 itemPerPage + 1 中查询一个额外的项目并将其作为参考。然后使用 startAtendAt 选项,我可以使用参考项在我的数据上翻页。

我创建了一个 Gist 来展示我的解决方案,希望它能有所帮助。