使用 keyPath 在 IDBObjectSore 中创建 indexedDB 索引的方法如下:'location:location._id'
Way to create indexedDB index in IDBObjectSore with keyPath like this: 'location:location._id'
我在 indexedDB 存储中有一些数据,如下所示:
{
"assetNo" : "00045455",
"location:location" : {
"title" : "19100003BRMA2879",
"_id" : "5e2727cbc38a923f5826efb7"
}
}
我想在该位置内的 _id 上创建一个索引,但 indexedDB 似乎不喜欢 location:location 之间的那个冒号。我收到一个错误:
DOMException:无法在 'IDBObjectStore' 上执行 'createIndex':keyPath 参数包含无效的密钥路径
冒号是千行万行代码中使用的约定,所以仅仅更改它就会有问题。有什么办法解决这个问题吗?例如,一种转义冒号的方法?
查看 https://www.w3.org/TR/IndexedDB-2/#key-path-construct 我看到它指出:
A valid key path is one of:
- An empty string.
- An identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].
- A string consisting of two or more identifiers separated by periods (U+002E FULL STOP).
- A non-empty list containing only strings conforming to the above requirements.
Spaces are not allowed within a key path.
冒号似乎违反了第二个要点。
您可以更改写入数据库和从数据库读取的数据吗?这是存储数据时很常见的事情,有时您需要修改实际持久化的内容。
类似于:
function write(db, object) {
return new Promise((resolve, reject) => {
const transaction = db.transaction('mystore', 'readwrite');
transaction.oncomplete = resolve;
transaction.onerror = event => reject(event.target.error);
const store = transaction.objectStore('mystore');
// what i am suggesting, modify just before write
// the extra cloning is to avoid side effects on input
const clone = { ...object };
clone.location_location = clone['location:location'];
delete clone['location:location'];
store.put(clone);
});
}
function onupgradeneeded(event) {
const db = event.target.result;
const store = db.createObjectStore('mystore');
db.createIndex('location_id', 'location_location._id');
}
function getByLocationId(db, id) {
return new Promise((resolve, reject) => {
const transaction = db.transaction('mystore');
const store = transaction.objectStore('mystore');
const index = store.index('location_id');
const request = index.get(id);
request.onerror = event => reject(request.error);
request.onsuccess = event => {
const result = event.target.result;
// if we found something, project output as if we stored
// it with a colon. we do not need to clone here.
if (result) {
result['location:location'] = result.location_location;
delete result.location_location;
}
resolve(result);
};
});
}
我在 indexedDB 存储中有一些数据,如下所示:
{
"assetNo" : "00045455",
"location:location" : {
"title" : "19100003BRMA2879",
"_id" : "5e2727cbc38a923f5826efb7"
}
}
我想在该位置内的 _id 上创建一个索引,但 indexedDB 似乎不喜欢 location:location 之间的那个冒号。我收到一个错误: DOMException:无法在 'IDBObjectStore' 上执行 'createIndex':keyPath 参数包含无效的密钥路径
冒号是千行万行代码中使用的约定,所以仅仅更改它就会有问题。有什么办法解决这个问题吗?例如,一种转义冒号的方法?
查看 https://www.w3.org/TR/IndexedDB-2/#key-path-construct 我看到它指出:
A valid key path is one of:
- An empty string.
- An identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].
- A string consisting of two or more identifiers separated by periods (U+002E FULL STOP).
- A non-empty list containing only strings conforming to the above requirements.
Spaces are not allowed within a key path.
冒号似乎违反了第二个要点。
您可以更改写入数据库和从数据库读取的数据吗?这是存储数据时很常见的事情,有时您需要修改实际持久化的内容。
类似于:
function write(db, object) {
return new Promise((resolve, reject) => {
const transaction = db.transaction('mystore', 'readwrite');
transaction.oncomplete = resolve;
transaction.onerror = event => reject(event.target.error);
const store = transaction.objectStore('mystore');
// what i am suggesting, modify just before write
// the extra cloning is to avoid side effects on input
const clone = { ...object };
clone.location_location = clone['location:location'];
delete clone['location:location'];
store.put(clone);
});
}
function onupgradeneeded(event) {
const db = event.target.result;
const store = db.createObjectStore('mystore');
db.createIndex('location_id', 'location_location._id');
}
function getByLocationId(db, id) {
return new Promise((resolve, reject) => {
const transaction = db.transaction('mystore');
const store = transaction.objectStore('mystore');
const index = store.index('location_id');
const request = index.get(id);
request.onerror = event => reject(request.error);
request.onsuccess = event => {
const result = event.target.result;
// if we found something, project output as if we stored
// it with a colon. we do not need to clone here.
if (result) {
result['location:location'] = result.location_location;
delete result.location_location;
}
resolve(result);
};
});
}