2012-03-30 62 views
1

我正在嘗試構建一個小型類容器,它將使它從HTML5 IndexedDB中加載和存儲數據變得更簡潔。說實話,這是我第一次玩這個功能,所以我的問題可能是微不足道的。當使用indexedDB時,對象沒有方法「打開」錯誤

我立足我的代碼關閉此教程: http://www.html5rocks.com/en/tutorials/indexeddb/todo/

function DBDictionary() 
{ 
    this.Holder = {}; 
    this.Entries = new Array(); 
    this.Opened = false; 
    this.v = "1.0"; 
    this.Holder.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB; 

    if ('webkitIndexedDB' in window) 
    { 
     window.IDBTransaction = window.webkitIDBTransaction; 
     window.IDBKeyRange = window.webkitIDBKeyRange; 
    } 

    this.Holder.indexedDB = {}; 
    this.Holder.indexedDB.db = null; 

    this.Holder.indexedDB.onerror = function(e) 
    { 
     console.log(e); 
    }; 

    this.DownloadDB = function() 
    { 
     if(this.Opened) return; 
     var request = this.Holder.indexedDB.open("Storage"); 
     request.onsuccess = function(e) 
     { 
      this.Holder.indexedDB.db = e.target.result; 
      var db = this.Holder.indexedDB.db; 
      // We can only create Object stores in a setVersion transaction; 
      if (v!= db.version) 
      { 
       var setVrequest = db.setVersion(v); 

       // onsuccess is the only place we can create Object Stores 
       setVrequest.onerror = this.Holder.indexedDB.onerror; 
       setVrequest.onsuccess = function(e) 
       { 
        if(db.objectStoreNames.contains("Storage")) db.deleteObjectStore("Storage"); 
        var store = db.createObjectStore("Storage", {keyPath: "Key"}); 
        this.PopulateAll(); 
       }; 
      } 
      else 
      { 
       this.PopulateAll(); 
      } 
     }; 

     request.onerror = this.Holder.indexedDB.onerror; 
    }; 

    this.UploadDB = function() 
    {  
     this.DeleteAll(); 
     this.SaveAll(); 
    }; 

    this.DeleteAll = function() 
    { 
     var db = this.Holder.indexedDB.db; 
     var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE); 
     var store = trans.objectStore("Storage"); 

     Entries.forEach(function(element, index, array) 
     { 
      var request = store.delete(index); 

      request.onerror = function(e) 
      { 
       console.log("Error Deleting: ", e); 
      }; 
     }); 
    }; 

    this.PopulateAll = function() 
    { 
     var db = this.Holder.indexedDB.db; 
     var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE); 
     var store = trans.objectStore("Storage"); 

     // Get everything in the store; 
     var keyRange = IDBKeyRange.lowerBound(0); 
     var cursorRequest = store.openCursor(keyRange); 

     cursorRequest.onsuccess = function(e) 
     { 
      var result = e.target.result; 

      //No more results to load 
      if(!!result == false) 
      { 
       if(!this.Opened) this.Opened = true; 
       return; 
      } 

      this.Entries[result.Key] = result.Value; 
      result.continue(); 
     }; 

     cursorRequest.onerror = this.Holder.indexedDB.onerror; 
    }; 

    this.SaveAll = function() 
    { 
     var db = this.Holder.indexedDB.db; 
     var trans = db.transaction(["Storage"], IDBTransaction.READ_WRITE); 
     var store = trans.objectStore("Storage"); 

     Entries.forEach(function(element, index, array) 
     { 
      var data = { 
       "Key": index, 
       "Value": element, 
       "timeStamp": new Date().getTime() 
      }; 

      var request = store.put(data); 

      request.onerror = function(e) { 
       console.log("Error Adding: ", e); 
      }; 
     }); 
    }; 
} 

function main() 
{ 
    var dictionary = new DBDictionary(); 
    dictionary.DownloadDB(); 

    dictionary.Entries["hello"] = "world"; 
    alert(dictionary.Entries["hello"]); 
} 

$(document).ready(main); 

我期望實現的狀態應該是這個樣子:

function main() 
{ 
    var dictionary = new DBDictionary(); 
    dictionary.DownloadDB(); 

    dictionary.Entries["hello"] = "world"; 
    alert(dictionary.Entries["hello"]); 
} 

$(document).ready(main); 

這是什麼應該做的是下載數據從瀏覽器的IndexedDB對象中存儲到對象控制的數組中。當我想將Entires的值存回數據庫時,我會調用dictionary.UploadDB();

但是,我得到單個JavaScript錯誤:未捕獲TypeError:對象#沒有方法'打開'。對於我做錯了什麼,我幾乎不知所措。任何人都可以提供一些提示嗎?

+0

您可能正在使用不支持IndexDB的瀏覽器 – 2012-03-30 06:18:24

+0

不,它的確如此;我正在使用最新版本的Chrome。簡單地按照教程工作正常,但我的實施沒有。 – 2012-03-30 06:38:34

回答

2

做一個打印檢查和console.logthis.Holder.indexedDB對象檢查原型。它是否繼承IDBDatabase原型?如果確實如此,則可以使用open方法。

如果您的window.indexedDB確實觸發了成功回調,e.target.result將是通過事件對象訪問新打開的數據庫的正確方法。但事實上,你沒有達到那麼遠表明你的this.Holder.indexedDB對象實際上並不是IDBDatabase的一個實例。

編輯:是的,這正是你的問題。如果你console.log this.holder.indexedDB對象,你會得到一個看起來像{"db":null}的對象。

交換this.Holder.indexedDBwindow.webkitIndexedDB在您的open調用,你會看到'世界'的警報彈出。 JSFiddle here

+0

腳註:此代碼僅適用於Chrome,因爲基於HTML5Rocks的示例使用舊版規範(2011年12月之前)。當你在當前規範中打開一個數據庫時,你需要傳遞一個版本號並實現一個'onupgradeneeded'回調。 – buley 2012-03-31 17:42:33

+1

忘記把它設置爲一段時間後的答案,但你對這些錢是正確的。謝謝! – 2012-05-10 00:06:24

相關問題