更新indexedDB中的对象时避免ConstraintError

时间:2014-02-05 14:48:28

标签: javascript indexeddb

我有一个SET函数,它使用特定键将对象设置为IndexedDB:

_that.set = function(data, key) {
    var transaction = _db.transaction([_tblName], "readwrite"),
        store = transaction.objectStore(_tblName), 
        request = store.add(data, key);

    request.onerror = function(e) {
        console.log("Error", e.target.error.name);
    };

    request.onsuccess = function(e) {
        console.log("Added to db successfully.");
    };
};

我有一个UPDATE函数,它使用特定键更新IndexedDB中的对象:

_that.update = function(data, key) {

    var transaction = _db.transaction([_tblName], "readwrite"),
        store = transaction.objectStore(_tblName),
        request = store.put(data, key);

    request.onerror = function(e) {
        console.log("Error", e.target.error.name);
    };

    request.onsuccess = function(e) {
        console.log("Object been updated", key);
    };
};

我有GET功能:

_that.get = function(key, callback) {

    if (key === "" || isNaN(key)) {
        return;
    }

    var transaction = _db.transaction([_tblName], "readonly"), 
        store = transaction.objectStore(_tblName), 
        request = store.get(key);

    request.onsuccess = function(e) {
        var res = e.target.result;
        callback(key, res);
    };
};

我想为IndexedDB创建SETORUPDATE函数,它将作为SET函数工作,如果onerror事件将调用GET函数,更新数据然后调用UPDATE函数。错误是ConstraintError,这意味着具有相应密钥的对象已存在于数据库中。有没有办法避免在控制台中出现此错误,而是触发GET和UPDATE?注意:前面带有下划线符号的变量是在Class顶部声明的实例变量,并在构造函数中初始化。

更新:我需要在使用相同的密钥更新数据变量之前更改数据变量的值,以防表中已存在具有某个对象的密钥。这就是为什么在更新之前检查相同的密钥是否已存在是很重要的。我想要这样的东西:

_that.setOrUpdate = function(data, key) {
    var transaction = _db.transaction([_tblName], "readwrite"),
        store = transaction.objectStore(_tblName), 
        request = store.add(data, key);

    request.onsuccess = function(e) {
        console.log("Added to db successfully.");
    };

    request.onerror = function(e) {
        _that.get(key);
        // make some changes to the data
        _that.update(data, key);
    };
};

2 个答案:

答案 0 :(得分:2)

That is already what IDBObjectStore.put does.如果密钥已经存在,它将更新一个对象,否则它将添加一个新对象。因此,您可以将update函数重命名为setorupdate并在任何地方使用它。

答案 1 :(得分:0)

我实际上已经弄明白了。我可以先使用GET方法,然后在ONSUCCESS上使用UPDATE。

_that.setOrUpdate = function(newValSerialized, key) {
    var transaction = _db.transaction([_tblName], "readwrite"),
        store = transaction.objectStore(_tblName),
        request = store.get(key);

    request.onsuccess = function(e) {
        var oldValSerialized = e.target.result;

        // make changes to data and put it as newVal object.           
        requestUpdate = store.put(newVal, key);

    };

    request.onerror = function(e) {
        console.dir(e.target.error.name);
    };
};

这个想法是GET方法永远不会返回ConstraintError。它要么找到它,要么给出未定义的。 Update方法也可以更新或添加。因此,我在控制台中看不到错误。