2015-10-07 44 views
0

我在嘗試學習如何使用IndexedDb,並且我的下一步是從商店獲取結果頁面。我的策略是將檢索的最後一個關鍵字存儲在服​​務中,並使用該關鍵字將該關鍵字作爲下一個請求的下限來打開遊標。下面是我最初定義它的函數:使用光標從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. 將繼續函數會拋出一個錯誤(所以我使用try/catch,解析catch塊中的數組值)
  2. 遊標將返回相同的值,pageSize次(所以我試着檢查當前循環迭代中的主鍵是否與最後一次匹配一個)

雖然這仍然不起作用。現在商店中有兩件商品,如果我調用這個函數,它會得到第一個商品,然後拋出一個錯誤,說明光標正在迭代或超過其結束。

我是否錯過了這應該如何工作?我只會使用getAll,但這是針對Cordova應用程序的,並且該方法不可用。我怎樣才能獲得一定數量的結果?

回答

0

我想通了。該規範並沒有完全明確,但在調用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); 
}