angular - 如何在 Angular(6) 和 firebase Firestore 设置中分页返回到以前的页面
问题描述
在将 Angular 与 Cloud Firestore (Firebase) 一起使用时,似乎有很多示例、教程和视频说明如何分页到下一页。
但经过广泛搜索后,我找不到分页到上一页的方法。我得到的最远的只是回到第一页。
这是我的服务现在的样子:
import { Injectable } from '@angular/core';
import { AngularFirestore } from 'angularfire2/firestore';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Task } from './task.model';
@Injectable()
export class TaskService {
private _data: BehaviorSubject<Task[]>;
public data: Observable<Task[]>;
firstEntry: any;
latestEntry: any;
constructor(private afs: AngularFirestore) { }
public first() {
this._data = new BehaviorSubject([]);
this.data = this._data.asObservable();
const tasksRef = this.getCollection('tasks', ref => ref.orderBy('createdAt').limit(5))
.subscribe(data => {
this.firstEntry = data[0].doc;
this.latestEntry = data[data.length - 1].doc;
this._data.next(data);
});
}
public next() {
const tasksRef = this.getCollection('tasks', ref => ref.orderBy('createdAt').startAfter(this.latestEntry).limit(5))
.subscribe(data => {
if (data.length) {
this.firstEntry = data[0].doc;
this.latestEntry = data[data.length - 1].doc;
this._data.next(data);
}
});
}
public previous() {
const tasksRef = this.getCollection('tasks', ref => ref.orderBy('createdAt').endBefore(this.firstEntry).limit(5))
.subscribe(data => {
if (data.length) {
this.firstEntry = data[0].doc;
this.latestEntry = data[data.length - 1].doc;
this._data.next(data);
}
});
}
private getCollection(ref, queryFn?): Observable<any[]> {
return this.afs.collection(ref, queryFn).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
const doc = a.payload.doc;
return { id, ...data, doc };
});
})
);
}
}
初始加载(第一页)有效,并且所有下一页都按预期工作。但似乎endBefore(this.firstEntry)
没有正确的光标,并再次导致第一页。
导航回上一页的正确方法是什么?
如果有人知道完整的教程或工作分页器的示例,请分享...
解决方案
import * as firebase from 'firebase/app';
import { last } from 'lodash';
import { dropRight } from 'lodash';
安装这个 npm 包(Lodash,Firebase)
导入 firebase 后,从 lodash 导入 last 和 dropRight。Last 方法返回数组的最后一个元素。DropRight 方法对数组的最后一个元素进行切片。
allEntry: Array<any[]> = [];
firstEntry = [];
lastEntry;
创建三个变量并将 firstEntry 分配给一个数组,以便将第一个数据存储在查询中。AllEntry 存储从查询中检索到的所有数据。LastEntry 将最后一个元素存储在 allEntry 中,该元素将用作游标以获取之后的数据。
getMainEntry() {
return this.afs.collection('tasks', ref => ref.orderBy('createdAt').limit(5)).valueChanges().subscribe(data => {
this.allentry = data;
firebase.firestore().collection('tasks').doc(data[data.length - 1]['key']).onSnapshot(c => {
this.lastentry = c;
firebase.firestore().collection('tasks').doc(data[0]['key']).onSnapshot(da => {
this.firstEntry.push(da);
});
});
});
}
这个 getMainEntry 函数获取集合中的数据,通过 createdAt 对其进行排序并将其限制为 5。然后获取 allEntry 数组中最后一个元素的文档快照并将其分配给 lastEntry。在获取并将 allEntry 数组中第一个元素的文档快照推送到 firstEntry 数组中之后。
现在让我们创建下一个函数
getNextData(){
const entarr = [];
firebase.firestore().collection('tasks').orderBy('createdAt').startAfter(this.lastEntry).limit(5).get().then((data) => {
data.docs.map(a => {
entarr.push(a.data());
this.allEntry = entarr;
});
}).then(() => {
firebase.firestore().collection('tasks').doc(entarr[entarr.length - 1]['key']).onSnapshot(data => {
this.lastEntry = data;
});
}).then(() => {
firebase.firestore().collection('tasks').doc(entarr[0]['key']).onSnapshot(da => {
this.firstEntry.push(da);
});
});
}
getNextData 函数获取集合中的下一个数据,通过 createdAt 对其进行排序,并将其限制为 lastEntry 之后的下 5 个数据。然后获取 entarr 数组中最后一个元素的文档快照并将其分配给 lastEntry。在获取并将 allEntry 数组中第一个元素的文档快照推送到 firstEntry 数组中之后。
以前的功能
getPrevData() {
const entarr = [];
this.firstEntry = dropRight(this.firstEntry);
const firstEntry = last(this.firstEntry);
firebase.firestore().collection('tasks').orderBy('createdAt').startAt(firstEntry).limit(5).get().then((d) => {
d.docs.map(a => {
entarr.push(a.data());
this.allEntry = entarr;
});
}).then(() => {
firebase.firestore().collection('tasks').doc(entarr[entarr.length - 1]['key']).onSnapshot(da => {
this.lastEntry = da;
});
});
}
希望这会很有用。
推荐阅读
- node.js - 无法连接到 MongoDB 服务器
- ktor - 在 http 异常的情况下,responsePipeline 在 requestPipeline 中捕获该异常后无异常执行
- javascript - 您好,在理解 TypeERROR 时遇到了一点问题:“无法读取未定义的属性 'map'”
- python - 如何编写正则表达式以接受以字符串结尾的字符串
- mutability - Zig 中的全局“comptime var”
- javascript - 使php脚本等到ajax请求完成
- sql-server - 似乎 BULK INSERT 的默认值是制表符分隔的输入数据?
- java - 如何使用 Java 查找主题中存在的消息数、主题中存在的分区数?
- android - 获取手机中正在运行的应用程序列表
- google-apps-script - 谷歌表格,将一行移动到另一张表格