我正在尝试学习如何使用IndexedDb,我的下一步是从商店获取一页结果。我的策略是在服务中存储为页面检索的最后一个密钥,并使用该密钥作为下一个请求的下限打开游标。这是我最初定义的函数:
service.getListPage = function(store, pageSize) {
pageSize = pageSize || 15;
var deferred = $q.defer();
//called on cursor open success event
var getPage = function (cursorEvent) {
var page = [];
var cursor = cursorEvent.target.result;
if (cursor) {
for (var i = 0; i < pageSize; i++) {
page.push(cursor.value);
cursor.continue();
}
lastKeyOnPage[store] = cursor.key;
deferred.resolve(page);
} else {
deferred.resolve([]);
}
}
var transaction = service.db.transaction([store], "readonly");
var objectStore = transaction.objectStore(store);
var cursor;
if (lastKeyOnPage.hasOwnProperty(store) && lastKeyOnPage[store]) {
cursor = objectStore.openCursor(IDBKeyRange.lowerBound(lastKeyOnPage[store]));
} else {
cursor = objectStore.openCursor();
}
cursor.onsuccess = getPage;
return deferred.promise;
}
如果我试图在商店中只使用一个项目来使用此功能,我遇到了两个问题:
pageSize
次(所以我尝试检查当前循环迭代中的主键是否与最后一个匹配)我错过了一些关于它应该如何工作的内容吗?我只想使用getAll,但这适用于Cordova应用程序,并且该方法不可用。我怎样才能获得一定数量的结果?
答案 0 :(得分:0)
我明白了。规范并没有完全明显,但在调用onsuccess
之后调用cursor.continue()
事件处理程序,因此不需要显式循环。固定方法如下所示:
var pageFunction = function(store, pageSize, direction) {
pageSize = pageSize || defaultPageSize;
var deferred = $q.defer();
var counter = pageSize;
var page = [];
if (!keys[store]) {
keys[store] = {};
}
//query function
var getPage = function (cursorEvent) {
var cursor = cursorEvent.target.result;
if (cursor && (counter < 0 || counter--)) {
if (direction) {
if (counter == pageSize - 1) {
keys[store][direction == "prev" ? first : last] = cursor.key;
}
keys[store][direction == "prev" ? last : first] = cursor.key;
}
page.push(cursor.value);
cursor.continue();
}
}
var transaction = service.db.transaction([store], "readonly");
var objectStore = transaction.objectStore(store);
var rangeStart = null;
if (direction) {
var bound = direction == "prev" ? upperBound : lowerBound;
rangeStart = keys[store].first
? IDBKeyRange.bound(keys[store].first)
: null;
}
var cursor = objectStore.openCursor(rangeStart, direction);
cursor.onsuccess = getPage;
transaction.oncomplete = function () { deferred.resolve(q(page)); }
return deferred.promise;
}
var pageAvailability = function(bound) {
var deferred = $q.defer();
var transaction = service.db.transaction([store], "readonly");
var objectStore = transaction.objectStore(store);
var countRequest = objectStore.count();
cursor.onsuccess = function (response) {
deferred.resolve(response > 0);
}
return deferred.promise;
}
service.prevPage = function (store, pageSize) {
return pageFunction(store, pageSize, "prev");
}
service.hasPrev = function (store) {
return pageAvailability(IDBKeyRange.upperBound(keys[store].last));
}
service.hasNext = function() {
return pageAvailability(IDBKeyRange.lowerBound(keys[store].first));
}
service.nextPage = function(store, pageSize) {
return pageFunction(store, pageSize, "next");
}
service.thisPage = function(store, pageSize) {
return pageFunction(store, pageSize);
}