如何使用自动增量键更新IndexedDB项目?

问题描述

我使用autoIncrement创建了一个对象存储:db.createObjectStore("items",{autoIncrement:true});

现在,我希望能够根据给定的键和新值来更新它,因此我编写了此函数

let updateItem = (key,newData) => {
    let objectStore = db.transaction(["items"],"readwrite").objectStore("items");
    let request = objectStore.get(key);
    request.onsuccess = (e) => {
        let data = e.target.result;
        Object.assign(data,newData);
        let requestUpdate = objectStore.put(data);      
    };
}

但是,它不会更新值,而是使用新数据创建一个新项目。我认为这很有意义,因为e.target.result不包含任何有关其键的信息。那么如何更新此类对象存储中的元素?

解决方法

您需要添加一个键作为第二个参数,例如 return ( <div> <Button label={increaseLabel} onClick={(e) => clickHandler(e,"foo")} /> <Button label={decreaseLabel} onClick={(e) => clickHandler(e,"bar")} /> <br/> <h2>{count}</h2> </div> )

您要更新的记录的主键(例如来自IDBCursor.primaryKey的记录)。只有具有objectStore.put(data,key)主键的对象存储才需要此操作,因此该键不在记录对象上的字段中。在这种情况下,调用autoIncrement总是会插入一条新记录,因为它不知道您可能要修改哪些现有记录。

-IDBObjectStore.put() - Web APIs | MDN

,

我使用cursor.update()找到了另一个解决方案:

let updateItem = (key,newData) => {
    let objectStore = db.transaction("items","readwrite").objectStore("items");
    objectStore.openCursor().onsuccess = (e) => {
        let cursor = e.target.result;
        if (cursor && cursor.key == key) {
            cursor.update(Object.assign(cursor.value,newData));
            cursor.continue();
        }
    };
}