IndexedDB 中的无效键路径: 限制?

7
我想创建一个非常简单的IndexedDB,使用一些JavaScript,但在on处理程序中失败了。 显然,浏览器(Chrome 57)无法解析我的存储中keyPath(在基本概念中)。 我大致遵循这些简单的示例:MDNOpera-Dev
假设我想在数据库中存储像这样的对象:
{
    "1": 23, // the unique id
    "2": 'Name',
    "3": 'Description',
    "4": null,
    "5": null
}

这是代码:

var sStoreNodes = 'nodes';
var sIdFieldNode = '1'; // the important part

// event is fired for creating the DB and upgrading the version
request.onupgradeneeded = function(event)
{
    var db = event.target.result;

    // Create an objectStore for nodes. Unique key should be the id of the node, on property 1. 
    // So ID will be the key!
    var objectStore =  db.createObjectStore(
        sStoreNodes,
        {
            // changing to a plain string works, if it is a valid identifier and not just a strigified number
            'keyPath'       : [ sIdFieldNode ],
            'autoIncrement' : false // really important here
        });
};

错误信息如下:

Uncaught DOMException: Failed to execute 'createObjectStore' on 'IDBDatabase': The keyPath option is not a valid key path. at IDBOpenDBRequest.CCapIndexedDB.request.onupgradeneeded

我也可以尝试省略关键路径,但我想知道为什么会发生这种情况,如果我确实需要使用(复杂的)关键路径,我该怎么办。
关于规范:
我不确定this是否适用于此处:

A value is said to be a valid key if it is one of the following ECMAScript [ECMA-262] types: Number primitive value, String primitive value, Date object, or Array object.

并且this实际上意味着什么:
如果键路径是DOMString,则获取键路径的值将是等于键路径的DOMString。如果键路径是序列,则该值将是一个新的数组,通过追加与序列中每个DOMString相等的字符串来填充。
如果你使用字符串而不是字符串化的数字,那么这个方法是可行的,因为字符串是一个有效的标识符(以字符[a-zA-Z]开头)。所以,'keyPath' : 'b' 是可以的。我猜这是因为这个值用来创建路径,比如 a.b.c
1个回答

6

这里是关键路径的定义,来自规范:

关键路径是一个DOMString或序列,用于定义如何从值中提取关键字。有效的关键路径之一为:

  • 一个空的DOMString。
  • 标识符,即与ECMAScript语言规范[ECMA-262]中的IdentifierName产生式匹配的DOMString。
  • 由两个或多个由句点(ASCII字符代码46)分隔的标识符组成的DOMString。
  • 仅包含符合上述要求的DOMString的非空序列。

对于包含整数的字符串,显然第一、第三和第四个选项不适用。对于第二个选项,我们需要查看什么是IdentifierName,这有点复杂,但基本上它必须以字母、下划线或美元符号开头。这意味着仅包含整数的字符串不是有效的关键路径。

如果您确实有一个主键在字段名称为包含整数的字符串的对象中,您可以重命名该字段或不使用键路径(在这种情况下,您必须手动将键指定为IDBObjectStore.addIDBObjectStore.put的第二个参数)。
您链接到密钥定义,它定义了密钥可以具有的有效值(例如对于对象{a:1},其中密钥路径为'a',密钥为1,这是有效的)。 您链接到的其他内容是关于键路径,如a.b.c引用{a:{b:{c:1}}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接