2013-03-09 86 views
7

如果密钥已存在,则将对象添加到IndexedDB objectStore将失败。我怎样才能用一个给定的键检查对象的存在 - 最好是同步的(没有理由为另一层回调)并且不用拉对象。检查IndexedDB objectStore是否已经包含密钥

我知道如何通过事务异步获取请求,但每次我想添加一个对象时,似乎都会经历一些折磨。

解决方案只在Chrome中工作(如果这能帮助)

回答

6

到目前为止,浏览器没有实现同步API,因此您必须将其设置为异步。一个objectStore公开了一个get方法,它提供了一个关键字,它会返回与该关键字匹配的对象(或null)。

有上MDN一个很好的教程,介绍了使用IDB和getting a record覆盖过,但联的代码是:

db.transaction("customers").objectStore("customers").get("444-44-4444").onsuccess = function(event) { 
    alert("Name for SSN 444-44-4444 is " + event.target.result.name); 
}; 

如果您不想检索记录,那么你可以随时使用count方法在索引here in the spec解释。根据这一结果,您可以使用addput来修改记录,如果不需要,它将保存提取记录。

+0

理想情况下,我不会拉出并初始化一条记录(某些对象有很多深度嵌套的数据)。寻找类似于SQL的EXISTS的东西。我知道indexedDB不是基于SQL的,但是像Redis这样的其他键值存储支持检查密钥的存在 – Chris 2013-03-12 16:40:33

+0

@Chris - nah没有这样的方法,我已经添加了另一种替代方法来解决这个问题,我想要水合对象 – 2013-03-12 22:36:11

+0

那么,它回答它,但不是我希望的哈哈。谢谢! – Chris 2013-03-12 22:46:41

10

检查一个键值存在的最好办法是objectStore.count(键)。这是异步的。

在你的情况下,最好的选择是你的钥匙openCursor。如果存在,光标会出现。

var req = objectStore.openCursor(key); 
req.onsuccess = function(e) { 
    var cursor = e.target.target; 
    if (cursor) { // key already exist 
    cursor.update(obj); 
    } else { // key not exist 
    objectStore.add(obj) 
    } 
}; 
+2

是的,这似乎是最接近我想要的东西。在承诺上堆! – Chris 2013-03-12 16:37:25

1

问题是为什么你想知道这个?也许你应该使用另一种方法?

你可以使用自动增量,这样你不需要检查一个键是否存在,你总会得到一个唯一的。

您也可以使用put方法而不是add方法。如果密钥存在,并且密钥不存在,则数据将被更新,数据将被添加。

一切都取决于你想检查是否存在的原因。

+0

因为我构建的应用程序在安装时将JSON加载为演示数据。在测试中(在某些情况下),安装回调会多次触发,因此演示数据实际上已经存在(因为indexedDB未被擦除)。 – Chris 2013-03-12 16:36:48

+0

所以在这种情况下,你可以使用put方法。现有的数据将被覆盖,新的数据将被添加 – 2013-03-12 17:42:09

+1

好的,在这个非常特殊的情况下工作,但这不同于检查存在。这只是强迫数据进入数据库。还有其他一些情况下,我可以想象有人希望检查记录的存在,而不用拔出数据或强制更新它。 – Chris 2013-03-12 17:44:00

2

答案有点迟,但可能有助于其他人。我还是迷迷糊糊-as我guess-过同样的问题,但它是非常简单的:

如果要插入或更新的记录您使用objectStore.put(object)(help)
如果你只需要插入您使用objectStore.add(object)(help)

记录

因此,如果您使用add(object),并且记录关键字仍然存在于数据库中,它将不会被覆盖并引发错误0“ConstraintError:关键字已存在于对象存储区中”。

如果您使用put(object),它将被覆盖。

相关问题