2014-12-18 69 views
0

我得到的錯誤是:IndexedDB的無法插入數據

Uncaught InvalidStateError: Failed to execute 'createObjectStore' on 'IDBDatabase': The database is not running a version change transaction. 

這裏是代碼:

var Database = function (settings, catalogue) { 

     window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; 

     if (!window.indexedDB) { 
      throw new Error("IndexedDB not supported!"); 
     } 

     var that = this; 
     this.settings = settings; 
     this.catalogue = catalogue; 
     this.db = null; 

     var request = indexedDB.open(this.settings.name, this.settings.version); 

     request.onerror = function (e) { 
      //e.message = "Database initialization error"; 
      console.error("Database initialization error:", e); 
     }; 

     request.onsuccess = function (e) { 

      console.log("Database initialization success"); 

      // that.db = e.target.result; 
      // that.db.onerror = function (e) { 
      // console.error("Database error:", e.target.errorCode); 
      // }; 

     }; 

     request.onupgradeneeded = function (e) { 

      console.log("Database upgrade required"); 

      var db = e.target.result; 
       db.onerror = function (e) { 
        console.error("Database upgrade error:", e.target.errorCode); 
       }; 

      that.catalogue.retrieve(function (catalogue) { 

       console.log(catalogue) 

       var stores = {}; 

       for (var categoryKey in catalogue) { 

        var category = catalogue[categoryKey]; 

        if (category.length > 0) { 

         var schemaProduct = category[0]; 

         stores[categoryKey] = db.createObjectStore(categoryKey, { keyPath: "id" }); 

         for (var prop in schemaProduct) { 

          stores[categoryKey].createIndex(prop, prop, { unique: false }); 

         } 

         stores[categoryKey].transaction.oncomplete = function(e) { 

          var transaction = db.transaction(categoryKey, "readwrite").objectStore(categoryKey); 

          for (var productKey in category) { 
           transaction.add(category[productKey]); 
          } 


          console.log("Insertion complete!") // this never fires 
         } 


        } 

       } 

      }); 


     }; 



    } 

var database = new Database(this.options.store.database, new Catalogue(this.options.store.catalogue)); 

我需要一雙新眼睛,因爲我似乎無法理解爲什麼這不起作用我重寫了代碼幾次,但明顯我失去了一些東西。

PS:this.catalogue是一個具有從服務器獲取數據的ajax請求的對象。數據是正確的。

+0

我使用onupgradeneeded只改變模式。只有在數據庫打開請求成功事件後纔會插入數據。根據規格,你可以做,但爲什麼? MDN示例以這種方式使用,但我認爲這不是一個好的模式。 –

回答

1

只是一個猜測,但通常這是因爲你在一起使用兩個不同的異步系統。儘管在有限的情況下可能會發生,但您通常希望避免調用非索引數據庫ajax​​函數,如異步標記的XMLHttpRequest。一個簡單的解決方法是首先調用catalogue.retrieve,然後在catelogue.retrieve的回調中使用更高版本調用indexedDB.open。這樣,當VERSION_CHANGE事務處於活動狀態時,onupgradeneeded事務中的語句就會發生。現在,在調用catelogue.retrieve完成之前,它看起來事務處於活動狀態(onupgradeneeded函數完成並退出)。

換句話說,這樣做:

catelogue.retrieve(function(catelogue) { 
    var r = indexedDB.open(...); 
    r.onupgradeneeded = function() { 
    var db = r.result; 
    for(var k in catelogue) { 
    //... 
    db.createObjectStore(...); 
    } 
    }; 
}); 
+0

你是對的沒有想過這個。 thnx再次 – Syd