2013-03-09 126 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),它將被覆蓋。