IndexedDB keyPath 到对象深处的某个地方?

发布于 2024-10-19 14:58:41 字数 221 浏览 6 评论 0原文

当您在 IndexedDB 中创建 objectStore 或索引时,您可以指定一个“keyPath”,用于说明在对象中的何处查找应作为存储或索引上的键的值。我的对象如下所示:

{doc:{id:4}}

有没有办法让我指定一个获取该 ID 的 keyPath?我尝试打点它(keyPath =“doc.id”),但它不起作用。我是否必须将所有可能的键复制到对象的顶层?

When you create an objectStore or index in IndexedDB, you specify a "keyPath" that says where in your object to look for the value that should be the key on the store or index. I have objects that look like this:

{doc:{id:4}}

Is there a way for me to specify a keyPath that will get that ID? I tried dotting it (keyPath = "doc.id"), but it didn't work. Do I have to copy all my possible keys into the top layer of my objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怂人 2024-10-26 14:58:41

根据规范,您的点符号是正确的。浏览器应该遵循 使用键路径从值中提取键的步骤,这应该会产生您想要的功能。

Chrome 12 的工作原理如所述。我无法让 Firefox 4.0 或 5.0 以这种方式运行,并怀疑这是它们实现中的一个错误(或者它们实现时的规范不同)。

如果不包含句点,Firefox 4.0 - 5.0 可以正确解析关键路径。正如您所说,这意味着如果您希望对象在 Firefox 中工作,则必须在对象的顶层拥有键。

以下是一些工作示例代码(适用于 Chrome 12 和 Firefox 4.0 - 5.0),说明了差异:

(function () {

    var db, idb = window.mozIndexedDB || window.webkitIndexedDB;

    idb.open("test").onsuccess = function (ev) {
        db = ev.target.result;
        db.setVersion("1.0").onsuccess = setUpDatabase;
    };

    function setUpDatabase(ev) {
        var x, store;

        for (x = 0; x < db.objectStoreNames.length; x += 1) {
            db.deleteObjectStore(db.objectStoreNames[x]);
        }

        var store = db.createObjectStore("test", {
            keyPath: (window.mozIndexedDB) ? 'moz' : 'doc.webKit'
        });

        store.add({ moz: 1, doc: { webKit: 3, name: 'webkit!'  }});
        store.add({ moz: 3, doc: { webKit: 1, name: 'mozilla!' }});

        // Wait for the setVersion transaction to end...
        // This is an example. Typically control would return to the
        // event loop after this point.
        window.setTimeout(getSomeValue, 1000);
    };

    function getSomeValue() {
        db.transaction("test").objectStore("test").get(3).onsuccess = showValue;
    }

    function showValue(ev) {
        var value = ev.target.result.doc;
        alert('name: ' + value.name);
        // Don't forget to close your connections!
        db.close();
    }

}());

According to the specification, your dot notation is correct. The browser is supposed to follow the steps for extracting a key from a value using a key path, which should result in the functionality you desire.

Chrome 12 works as described. I have not been able to get Firefox 4.0 or 5.0 to behave this way, and suspect this is a bug in their implementation (or else the specification was different when they implemented it).

Firefox 4.0 - 5.0 DOES correctly parse a key path if it contains no periods. As you say, this means you must have keys at the top level of your object if you want it to work in Firefox.

Here is some working example code (for Chrome 12 and Firefox 4.0 - 5.0) that illustrates the difference:

(function () {

    var db, idb = window.mozIndexedDB || window.webkitIndexedDB;

    idb.open("test").onsuccess = function (ev) {
        db = ev.target.result;
        db.setVersion("1.0").onsuccess = setUpDatabase;
    };

    function setUpDatabase(ev) {
        var x, store;

        for (x = 0; x < db.objectStoreNames.length; x += 1) {
            db.deleteObjectStore(db.objectStoreNames[x]);
        }

        var store = db.createObjectStore("test", {
            keyPath: (window.mozIndexedDB) ? 'moz' : 'doc.webKit'
        });

        store.add({ moz: 1, doc: { webKit: 3, name: 'webkit!'  }});
        store.add({ moz: 3, doc: { webKit: 1, name: 'mozilla!' }});

        // Wait for the setVersion transaction to end...
        // This is an example. Typically control would return to the
        // event loop after this point.
        window.setTimeout(getSomeValue, 1000);
    };

    function getSomeValue() {
        db.transaction("test").objectStore("test").get(3).onsuccess = showValue;
    }

    function showValue(ev) {
        var value = ev.target.result.doc;
        alert('name: ' + value.name);
        // Don't forget to close your connections!
        db.close();
    }

}());
2024-10-26 14:58:41

正如您所发现的,在 Firefox 中 IndexedDB 的最初实现中,这并不能正常工作。

不过现在它已经被修复了一段时间了,所以你应该能够毫无问题地使用它。

In the initial implementation of IndexedDB in Firefox this didn't work correctly as you've discovered.

However by now it's been fixed for quite a while, so you should be able to use it without problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文