【问题标题】:Getting a page of results from IndexedDb using cursor使用游标从 IndexedDb 获取结果页面
【发布时间】:2015-10-07 12:28:45
【问题描述】:

我正在尝试学习如何使用 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;
}

如果我尝试在商店中仅使用一件商品时使用此功能,则会遇到两个问题:

  1. continue 函数会抛出错误(所以我使用了 try/catch,解析了 catch 块中的值数组)
  2. 游标会返回相同的值,pageSize 次(所以我尝试检查当前循环迭代中的主键是否与最后一个匹配)

不过,这仍然不起作用。商店里现在有两个项目,如果我调用这个函数,它会得到第一个项目,然后抛出一个错误,说光标正在迭代或超过它的结尾。

我是否遗漏了一些关于它应该如何工作的东西?我只会使用 getAll,但这是针对 Cordova 应用程序的,并且该方法不可用。我怎样才能只获取一定数量的结果?

【问题讨论】:

    标签: javascript indexeddb


    【解决方案1】:

    我想通了。规范并没有使它完全明显,但是在调用cursor.continue() 之后调用onsuccess 事件处理程序,因此不需要显式循环。固定方法如下所示:

     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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-07
      • 2015-08-12
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多