Firebase 使用AngularFire2分页

Firebase 使用AngularFire2分页,firebase,pagination,firebase-realtime-database,angularfire,angularfire2,Firebase,Pagination,Firebase Realtime Database,Angularfire,Angularfire2,我正在构建一个Ionic2项目,它使用Firebase,我正在使用AngularFire2 从AngularFire2文档中,我可以得到如下信息: const queryObservable = af.database.list('/items', { query: { orderByChild: 'size', equalTo: subject } }); 这很有效。我有大约300-400条记录,但我不能在一个API调用中提取所有记录。所以我尝试实现分页。我尝试了很

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

从AngularFire2文档中,我可以得到如下信息:

const queryObservable = af.database.list('/items', {
  query: {
    orderByChild: 'size',
    equalTo: subject 
  }
});
这很有效。我有大约300-400条记录,但我不能在一个API调用中提取所有记录。所以我尝试实现分页。我尝试了很多东西。我想实施的是:

我试图通过查询对象传递它,但它不起作用。 AngularFire2对此有实现吗?
如果没有,我如何获得Firebase ref,以便编写自己的实现?

AngularFire2根据它们的特性支持
startAt
endAt
。下面是基于子键为
大小的列表限制查询的方法:

let queryObservable = this.af.database.list('/items', {
  query: {
    orderByChild: 'size',
    startAt: 50,
    endAt: 100
  }
});
这将拉取所有具有定义在50到100之间的
大小的子键的项

注意我注意到,如果我将引用对象传递到AngularFire2而不是引用路径,查询将不起作用!因此,下面的代码仍将返回项目列表,但不会正确排序

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

AngularFire2根据各自的功能支持
startAt
endAt
。下面是基于子键为
大小的列表限制查询的方法:

let queryObservable = this.af.database.list('/items', {
  query: {
    orderByChild: 'size',
    startAt: 50,
    endAt: 100
  }
});
这将拉取所有具有定义在50到100之间的
大小的子键的项

注意我注意到,如果我将引用对象传递到AngularFire2而不是引用路径,查询将不起作用!因此,下面的代码仍将返回项目列表,但不会正确排序

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

我在最近的一篇文章中研究了这个问题,但您提出了一个有趣的边缘案例,其中您的总查询量将大于您想要提取的量。我将使用与以前相同的方法来解决这个问题,但是实现从开始到结束,而不是限制到最后。此外,您还可以使用从rxjs导入的BehaviorSubject,因为它们将允许您获取当前值并以一定数量递增。范例

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
 }
});
现在您有了一个不断移动的窗口,从第一个键开始,并使用这些键作为排序的值。例如,为了能够更改密钥,您需要将所需密钥存储在特定位置

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);
  }
});
要增加和减少窗口,只需将firstKey值更改为nextKey的值

firstKey.next(nextKey.getValue());

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

我最近在一篇文章中研究了这个问题,但您提出了一个有趣的边缘情况,即您的总查询量将大于您想要的查询量。我将使用与以前相同的方法来解决这个问题,但是实现从开始到结束,而不是限制到最后。此外,您还可以使用从rxjs导入的BehaviorSubject,因为它们将允许您获取当前值并以一定数量递增。范例

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
 }
});
现在您有了一个不断移动的窗口,从第一个键开始,并使用这些键作为排序的值。例如,为了能够更改密钥,您需要将所需密钥存储在特定位置

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);
  }
});
要增加和减少窗口,只需将firstKey值更改为nextKey的值

firstKey.next(nextKey.getValue());

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

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

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


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

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

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


我已经创建了一个用于显示我的解决方案,希望它能有所帮助。

如果不能简单地计算db行,如何进行分页?而它的workarround一次带来所有数据,那么为什么要用开始/结束限制再次查询它呢?我遗漏了什么?一种方法是使用
order
的子键,其中是一个递增计数器0、1、2、3等。然后您可以使用
orderByChild:“order”
startAt:10
endAt:19
以获取第二页的条目10-19。如果无法对db行进行简单计数,如何分页?而它的workarround一次带来所有数据,那么为什么要用开始/结束限制再次查询它呢?我遗漏了什么?一种方法是使用
order
的子键,其中它是一个递增计数器0、1、2、3等。然后您可以使用
orderByChild:“order”
startAt:10
endAt:19
来获取第二页的条目10-19。当我尝试检索数据时,我的$key总是未定义的。这是为什么?当我尝试检索数据时,我的$key总是未定义。为什么会这样?