indexedDB无法在数据库中插入数据" onupgradeneeded"事件

时间:2014-12-18 17:47:13

标签: javascript 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请求的对象,它从服务器获取数据。数据是正确的。

1 个答案:

答案 0 :(得分: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(...);
   }
  };
});