2012-03-30 7 views
1

Ich versuche, einen kleinen klassenähnlichen Container zu erstellen, der es ein wenig sauberer macht, Daten aus der HTML5 IndexedDB zu laden und zu speichern. Um ehrlich zu sein, dies ist das erste Mal, dass ich mit dieser Funktion gespielt habe, also könnte mein Problem trivial sein.Object hat keine Methode "open" -Fehler bei der Verwendung von indexedDB

Ich bin stützen meinen Code dieses Tutorial aus: 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); 

Mein Wunsch umgesetzt Zustand wie folgt aussehen sollte:

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

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

$(document).ready(main); 

Was dies tun sollten, ist die Daten herunterladen aus dem IndexedDB-Objekt des Browsers und speichert sie in den Array-Einträgen des Objektgehäuses. Wenn ich den Wert von Entires zurück in die DB speichern möchte, würde ich dictionary.UploadDB();

Allerdings bekomme ich den einzigen Javascript-Fehler: Uncaught TypeError: Object # hat keine Methode 'öffnen'. Ich bin ziemlich ratlos, was ich falsch mache. Kann mir jemand ein paar Tipps geben?

+0

Sie verwenden wahrscheinlich einen Browser, der IndexDB nicht unterstützt –

+0

Nein, tut es; Ich verwende die neueste Version von Chrome. Einfach dem Tutorial zu folgen funktioniert gut, aber meine Implementierung nicht. –

Antwort

2

Machen Sie eine Überprüfung und console.log das Objekt this.Holder.indexedDB, um den Prototyp zu überprüfen. Erbt es den IDBDatabase Prototyp? Wenn dies der Fall ist, steht Ihnen die Methode open zur Verfügung.

Wenn Ihr window.indexedDB den On-Erfolg-Callback ausgelöst hat, wäre e.target.result der richtige Weg, um über das Event-Objekt auf die neu geöffnete Datenbank zuzugreifen. Aber die Tatsache, dass Sie nicht so weit kommen, deutet darauf hin, dass Ihr this.Holder.indexedDB Objekt nicht wirklich eine Instanz von IDBDatabase ist.

BEARBEITEN: Ja, das ist genau dein Problem. Wenn Sie das Objekt this.holder.indexedDB console.log senden, erhalten Sie ein Objekt, das wie folgt aussieht: {"db":null}.

Tauschen Sie this.Holder.indexedDB für window.webkitIndexedDB bei Ihrer open Aufruf und Sie werden sehen, dass "Welt" Alarm erscheint. JSFiddle here.

+0

Fußnote: Dieser Code wird nur in Chrome funktionieren, da das HTML5Rocks-Beispiel, auf dem Sie basieren, die ältere Spezifikation verwendet (vor Dezember 2011). Wenn Sie eine Datenbank in der aktuellen Spezifikation öffnen, müssen Sie eine Versionsnummer übergeben und einen Rückruf "onupgradeeneded" implementieren. – buley

+1

Forgotten Sie dies als die Antwort von einer Weile zurück, aber Sie hatten Recht auf das Geld. Vielen Dank! –