我正在编写一个Chrome扩展程序,它使用IndexedDB
将一些信息客户端存储在IDBObjectStore
中的IDBDatabase
内。
数据的本质是我需要我的用户能够随心所欲地修改对象存储。 (添加新对象修改现有对象等)我通过设置页面完成此操作,到目前为止一切都很好。
当我想发布(默认)对象存储的新版本时,需要注意。如果我不关心覆盖用户的数据,那么我可以像处理它时处理onupgradeneeded
事件一样处理新事件。这将是:
var request = window.indexedDB.open(DB_NAME, CURRENT_DB_VERSION);
request.onupgradeneeded = upgrade;
function upgrade(event){
var db = event.target.result;
var objectStore = db.createObjectStore("domains", {keyPath: "id", autoIncrement: true});
objectStore.createIndex("domain", "domain", {multiEntry: true });
for(var i=0; i<tags.length; i++){
objectStore.add(tags[i]);
console.log("added " + tags[i]["domain"] + " to the IDBObjectStore 'domains' in the IDBDatabase 'Tags' (Format)");
}
}
......但我很在意。
所以,我目前正在做的是在upgrade(event)
函数中放置一个条件来检查event.oldVersion
(在全新安装时它的0)的真实性。如果该值大于0,那么我打开一个包含选项页面的新选项卡,用户可以在其中选择要更新的对象。
现在是棘手的部分:一旦此页面关闭,我需要向包含必要升级信息的后台页面发送消息。通常,我会在我的监听器中收到消息并使用提供的信息执行更新。但是,IDBDatabase.createObjectStore()
如果出现InvalidStateError
没有从版本更改事务回调中调用方法[。]
当我查看IDBDatabase.transaction(storenames, mode)
的规范时,在mode
参数说明中,它说:
versionchange
模式不能在这里指定。
所以,在我看来,我需要触发一个onupgradeneeded
事件,但我还需要向事件处理程序传递一个额外的参数,除了事件本身,它包含可用于决定如何执行升级。
我不知道如何去做这件事。
有人能给我一些见解吗?
答案 0 :(得分:3)
您收到InvalidStateError
,因为您可能无法从IDBDatabase.createObjectStore()
事件处理程序调用{{1}}。对于IDB,所有对象库的创建和操作都必须从onupgradeneeded
事件处理程序内部或触发onupgradeneeded
之后发生。
如果我正确理解了您的要求,那么您不希望在某些条件下覆盖用户的现有对象存储库,为此您希望在onupgradeneeded
事件处理程序中传递一些信息来判断是否要创建重新对象存储或在现有对象存储上进行一些修改。
我的建议是 - 有两个全局数组变量onupgradeneeded
和DB_SCHEMA_DROP_QUERIES
,您可以使用drop {#1}}
然后有如下代码(我只是抬头),所以当你想 1。创建重新数据库时,首先从数据库中删除所有现有的数据存储并创建新的(表示填充DB_SCHEMA_CREATE_QUERIES
和window.indexedDB.open(DB_NAME, CURRENT_DB_VERSION);
)。 2。只需添加一个对象库,然后只准备DB_SCHEMA_DROP_QUERIES
3。修改现有对象库,然后准备DB_SCHEMA_CREATE_QUERIES
和{{1}但仅适用于该特定对象库
基本上我们正在努力实现动态而不是硬编码数据存储创建,如DB_SCHEMA_CREATE_QUERIES
。这也可以帮助您摆脱维护版本记录。
DB_SCHEMA_DROP_QUERIES
答案 1 :(得分:3)
触发升级式事务(版本更改事务)的唯一方法是打开具有更大版本号的连接。