IndexedDB中的密钥路径无效:限制?

时间:2017-04-07 09:00:47

标签: javascript indexeddb key-value-store

我试图用一些JavaScript创建一个非常简单的IndexedDB,但它已经在on处理程序中失败了。显然,浏览器(Chrome 57)无法parse我的存储空间keyPathBasic Concepts)。

我或多或少地关注这些简单示例:MDNOpera-Dev

假设我想在DB中存储像这样的对象:

{
    "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
        });
};

错误消息如下:

  

未捕获的DOMException:无法执行' createObjectStore' on' IDBDatabase':keyPath选项不是有效的密钥路径。       在IDBOpenDBRequest.CCapIndexedDB.request.onupgradeneeded

我也可以尝试省略关键路径,但我想知道为什么会发生这种情况,如果我真的需要使用(复杂的)密钥路径,我想要这样做。

关于规范:

我不确定,this是否可以在这里应用:

  

如果值是以下ECMAScript [ECMA-262]类型之一,则称该值为有效密钥:Number原始值,String原始值,Date对象或Array对象。

以及this的实际含义:

  

如果密钥路径是DOMString,则[获取密钥路径]的值将是一个等于密钥路径的DOMString。如果键路径是一个序列,则该值将是一个新的Array,通过在序列中附加等于每个DOMString的字符串来填充。

编辑如果您不使用字符串化的数字,而是使用字符串,这是有效的标识符(以字符[a-zA-Z]开头),则此方法有效。所以'keyPath' : 'b'没问题。我想这是因为这个值用于创建像a.b.c这样的路径。

1 个答案:

答案 0 :(得分:4)

Here is the definition of a key path, from the spec:

  

密钥路径是DOMString或序列,用于定义如何从值中提取密钥。有效的密钥路径是以下之一:

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

对于包含整数的字符串,显然第一个,第三个和第四个选项不适用。对于第二个,我们必须看到what an IdentifierName is,这有点复杂,但基本上它必须以字母,下划线或美元符号开头。这意味着只包含整数的字符串不是有效的密钥路径。

如果确实有一个对象,其中主键位于一个字段,其名称是一个包含整数的字符串,您可以重命名该字段或不使用键路径(在这种情况下,您必须手动指定键为IDBObjectStore.addIDBObjectStore.put)的第二个参数。

您链接到the definition for a key,它定义了密钥可以拥有的有效值(例如密钥路径为{a: 1}的密钥为'a'的对象1 ,这是有效的。)

other thing you linked to与关键路径类似a.b.c引用{a: {b: {c: 1}}}