如何使用 Ionic Infinite Scroll 对 PouchDB 进行分页?
How to do pagination with PouchDB using Ionic Infinite Scroll?
假设我有 100 个文档(注意:文档总数肯定会增加)。一次获取所有 100 个文档会导致性能问题,所以我认为我需要进行无限滚动和显示,比方说,第一次加载时有 15 个文档。每次触发无限滚动,它应该再得到 15 个文档。
基本上,docArr.length = 100
首次加载:抓取 docArr[0]
至 docArr[14]
触发无限卷轴:抓取docArr[15]
到docArr[29]
等直到docArr[99]
也被抓取
在PouchDB FAQ on Pagination中说明需要使用startkey
、endkey
、limit
和skip
。
我的文档 ID 的格式为 doc-1
。所以我有 doc-1
、doc-2
、doc-3
等
我按照建议的方法使用,所以我的代码是;
var options = {limit : 15};
function fetchNextPage() {
pouch.allDocs(options, function (err, response) {
if (response && response.rows.length > 0) {
let id_num = response[response.length - 1]._id.split('-').pop()
//on first trigger, the line above should get '15'
id_num = Number(id_num) + 1
let id = 'doc-' + id_num
//on first trigger, id = 'doc-16'
options.startkey = id;
options.skip = 1;
}
// handle err or response
});
}
但是,当我这样做时,当我触发无限滚动时,即使我增加了 id(这我用作 startkey
).
如何在每次触发无限滚动(进行分页)时获取接下来的 15 个文档?
我不是 100% 清楚 OP 的代码是怎么回事,但是假设 _all_docs
的第一个查询的 response.rows
是有序的所以
rows index
id
0
doc-1
1
doc-2
2
doc-3
3
doc-4
4
doc-5
5
doc-6
6
doc-7
7
doc-8
8
doc-9
9
doc-10
10
doc-11
11
doc-12
12
doc-13
13
doc-14
14
doc-15
是错误的。文档 ID 是字符串,因此遵循 CouchDB 文档 3.2.2.5. Collation Specification.
中记录的整理规则
根据 OP 指定的文档 ID 格式,这应该是 实际 文档 ID 序列,由对 _all_docs
的初始调用返回:
rows index
id
0
doc-1
1
doc-10
2
doc-100
3
doc-11
4
doc-12
5
doc-13
6
doc-14
7
doc-15
8
doc-16
9
doc-17
10
doc-18
11
doc-19
12
doc-2
13
doc-20
14
doc-21
因此下一组结果的计算是有缺陷的
id_num = Number(id_num) + 1
let id = 'doc-' + id_num
options.startkey = id;
计算下一个 id 是个坏主意,完全没有必要。而是使用 最后一个文档的 ID,例如
let result = await db.allDocs(options);
if(result.rows.length) {
// do something with results
// get next page of docs?
if(result.rows.length === options.limit) {
options.startkey = result.rows.pop().id;
options.skip = 1;
// repeat
}
}
此代码段使用setTimeout
每秒抓取15个文档,将文档id记录到控制台,当返回的文档数量小于limit
时退出,表示结束结果。
// canned test documents
function getDocsToInstall() {
let docs = [];
for (let i = 1; i < 101; i++) {
docs.push({
_id: `doc-${i}`
});
}
return docs;
}
let db;
// init db instance
async function initDb() {
db = new PouchDB('test', {
adapter: 'memory'
});
await db.bulkDocs(getDocsToInstall());
}
function update(result) {
console.log(result.rows.map(d => d.id).join(','));
}
initDb().then(async() => {
let options = {
limit: 15,
include_docs: false,
reduce: false
};
async function timerFn() {
let result = await db.allDocs(options);
if (result.rows.length) {
update(result);
// get next page of docs
if (result.rows.length === options.limit) {
options.startkey = result.rows.pop().id;
options.skip = 1;
// repeat
setTimeout(timerFn, 1000);
} else {
console.log("All docs processed ");
}
}
};
timerFn();
});
<script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>
假设我有 100 个文档(注意:文档总数肯定会增加)。一次获取所有 100 个文档会导致性能问题,所以我认为我需要进行无限滚动和显示,比方说,第一次加载时有 15 个文档。每次触发无限滚动,它应该再得到 15 个文档。
基本上,docArr.length = 100
首次加载:抓取 docArr[0]
至 docArr[14]
触发无限卷轴:抓取docArr[15]
到docArr[29]
等直到docArr[99]
也被抓取
在PouchDB FAQ on Pagination中说明需要使用startkey
、endkey
、limit
和skip
。
我的文档 ID 的格式为 doc-1
。所以我有 doc-1
、doc-2
、doc-3
等
我按照建议的方法使用,所以我的代码是;
var options = {limit : 15};
function fetchNextPage() {
pouch.allDocs(options, function (err, response) {
if (response && response.rows.length > 0) {
let id_num = response[response.length - 1]._id.split('-').pop()
//on first trigger, the line above should get '15'
id_num = Number(id_num) + 1
let id = 'doc-' + id_num
//on first trigger, id = 'doc-16'
options.startkey = id;
options.skip = 1;
}
// handle err or response
});
}
但是,当我这样做时,当我触发无限滚动时,即使我增加了 id(这我用作 startkey
).
如何在每次触发无限滚动(进行分页)时获取接下来的 15 个文档?
我不是 100% 清楚 OP 的代码是怎么回事,但是假设 _all_docs
的第一个查询的 response.rows
是有序的所以
rows index | id |
---|---|
0 | doc-1 |
1 | doc-2 |
2 | doc-3 |
3 | doc-4 |
4 | doc-5 |
5 | doc-6 |
6 | doc-7 |
7 | doc-8 |
8 | doc-9 |
9 | doc-10 |
10 | doc-11 |
11 | doc-12 |
12 | doc-13 |
13 | doc-14 |
14 | doc-15 |
是错误的。文档 ID 是字符串,因此遵循 CouchDB 文档 3.2.2.5. Collation Specification.
中记录的整理规则根据 OP 指定的文档 ID 格式,这应该是 实际 文档 ID 序列,由对 _all_docs
的初始调用返回:
rows index | id |
---|---|
0 | doc-1 |
1 | doc-10 |
2 | doc-100 |
3 | doc-11 |
4 | doc-12 |
5 | doc-13 |
6 | doc-14 |
7 | doc-15 |
8 | doc-16 |
9 | doc-17 |
10 | doc-18 |
11 | doc-19 |
12 | doc-2 |
13 | doc-20 |
14 | doc-21 |
因此下一组结果的计算是有缺陷的
id_num = Number(id_num) + 1
let id = 'doc-' + id_num
options.startkey = id;
计算下一个 id 是个坏主意,完全没有必要。而是使用 最后一个文档的 ID,例如
let result = await db.allDocs(options);
if(result.rows.length) {
// do something with results
// get next page of docs?
if(result.rows.length === options.limit) {
options.startkey = result.rows.pop().id;
options.skip = 1;
// repeat
}
}
此代码段使用setTimeout
每秒抓取15个文档,将文档id记录到控制台,当返回的文档数量小于limit
时退出,表示结束结果。
// canned test documents
function getDocsToInstall() {
let docs = [];
for (let i = 1; i < 101; i++) {
docs.push({
_id: `doc-${i}`
});
}
return docs;
}
let db;
// init db instance
async function initDb() {
db = new PouchDB('test', {
adapter: 'memory'
});
await db.bulkDocs(getDocsToInstall());
}
function update(result) {
console.log(result.rows.map(d => d.id).join(','));
}
initDb().then(async() => {
let options = {
limit: 15,
include_docs: false,
reduce: false
};
async function timerFn() {
let result = await db.allDocs(options);
if (result.rows.length) {
update(result);
// get next page of docs
if (result.rows.length === options.limit) {
options.startkey = result.rows.pop().id;
options.skip = 1;
// repeat
setTimeout(timerFn, 1000);
} else {
console.log("All docs processed ");
}
}
};
timerFn();
});
<script src="https://cdn.jsdelivr.net/npm/pouchdb@7.1.1/dist/pouchdb.min.js"></script>
<script src="https://github.com/pouchdb/pouchdb/releases/download/7.1.1/pouchdb.memory.min.js"></script>