indexeddb ,如何使用游标更新对象数组
indexeddb , how to use a cursor to update an array of objects
问题:如何存储一个充满对象的大数组,所有对象都有 5 个属性,并且除了 id 属性 之外的所有对象都必须更新。此外,为什么下面的代码不起作用,我如何格式化它以解决主要问题?
我查看过的信息:
https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/openCursor
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/createIndex
注意:我知道 setInterval
及其低效,这是为了测试目的,所以我不必点击多次来检查结果。
<html>
<body>
<script type="text/javascript">
let count =0;
let storeBuilt = false;
const dbName = "the_name";
let version=82;
let storeName= "store82";
let storeBuilding= false;
setInterval(build,1000/24);
function build(){
hello()
}
function hello(){
let customerData = [];
for(let i=0;i<=50000;i++){
customerData.push({name:"bob",minX:random(),minY:random(),maxX:random(),maxY:random(),id:random()})
}
let request = indexedDB.open(dbName, version);
request.onsuccess= function(event){
let db = event.target.result;
let transaction = db.transaction( storeName,"readwrite").objectStore(storeName);
if( storeBuilding=== false&& storeBuilt=== false){
storeBuilding= true;
let additem = addData(customerData, transaction);
additem.onsuccess= function(e){storeBuilt=true}
} else if (storeBuilt=== true){
let updateitem= updateData(customerData, transaction);
}
};
request.onupgradeneeded = function(event) {
let db = event.target.result;
// Create an objectStore to hold information about our customers. We're
// going to use "ssn" as our key path because it's guaranteed to be
// unique - or at least that's what I was told during the kickoff meeting.
let objectStore = db.createObjectStore(storeName, {keyPath:"names",autoIncrement:true});
objectStore.createIndex("name","name",{unique:true});
// Use transaction oncomplete to make sure the objectStore creation is
// finished before adding data into it.
objectStore.transaction.oncomplete = function(event) {
// Store values in the newly created objectStore.
let customerObjectStore = db.transaction(storeName, "readwrite").objectStore(storeName);
}
};}
function random (){
return (Math.floor((Math.random() * 10) + 1))
}
function addData(data,transaction){
return transaction.add(data)
}
function updateData(data,transaction){
let openCursor = transaction.index("name").openCursor();
openCursor.onsuccess= function(event){
let cursor = event.target.result;
if (cursor){
alert (cursor);
for(let I in data){
let item = data[I];
if(item.id === cursor.value.id){
let updateProperty = cursor.value;
updateProperty.minX = item.minX;
cursor.update(updateProperty);
cursor.continue()
}
}
}{alert("none")}
}
}
function deleteData(data,transaction){
}
</script>
</body>
</html>
不确定我是否理解清楚问题,但通常你会想要从对象存储中加载对象,修改每个对象的属性,然后将对象存储在对象存储中。有几种方法可以做到这一点。一种方法是使用 cursor.update,但我认为您根本不需要这样做。只需覆盖对象。
function storeThings(db, things, callback) {
var txn = db.transaction('store82', 'readwrite');
txn.oncomplete = callback;
var store = txn.objectStore('store82');
for(var thing of things) {
store.put(thing);
}
}
function open(callback) {
var request = indexedDB.open();
request.onsuccess = _ => callback(request.result);
}
var things = [{id:1}, {id:2}, {id:3}];
open(db => storeThings(db, things, _ => console.log('done')));
我正在使用 IDBObjectStore.prototype.put 来存储对象。 put 方法将创建或覆盖存储中的对象。当根据键路径找不到匹配的对象时,它将在商店中创建一个新对象。当找到匹配的对象时,它将替换商店中的现有对象。
在您的例子中,您使用 ssn 字符串作为键路径。因此,换句话说,如果找不到 ssn,它将创建新人,如果找到 ssn,它将覆盖人。您只需要确保 ssn 属性 是在您传递给 put 的每个人对象中定义的,否则 indexedDB 会报错。
问题:如何存储一个充满对象的大数组,所有对象都有 5 个属性,并且除了 id 属性 之外的所有对象都必须更新。此外,为什么下面的代码不起作用,我如何格式化它以解决主要问题?
我查看过的信息:
https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/openCursor
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/createIndex
注意:我知道 setInterval
及其低效,这是为了测试目的,所以我不必点击多次来检查结果。
<html>
<body>
<script type="text/javascript">
let count =0;
let storeBuilt = false;
const dbName = "the_name";
let version=82;
let storeName= "store82";
let storeBuilding= false;
setInterval(build,1000/24);
function build(){
hello()
}
function hello(){
let customerData = [];
for(let i=0;i<=50000;i++){
customerData.push({name:"bob",minX:random(),minY:random(),maxX:random(),maxY:random(),id:random()})
}
let request = indexedDB.open(dbName, version);
request.onsuccess= function(event){
let db = event.target.result;
let transaction = db.transaction( storeName,"readwrite").objectStore(storeName);
if( storeBuilding=== false&& storeBuilt=== false){
storeBuilding= true;
let additem = addData(customerData, transaction);
additem.onsuccess= function(e){storeBuilt=true}
} else if (storeBuilt=== true){
let updateitem= updateData(customerData, transaction);
}
};
request.onupgradeneeded = function(event) {
let db = event.target.result;
// Create an objectStore to hold information about our customers. We're
// going to use "ssn" as our key path because it's guaranteed to be
// unique - or at least that's what I was told during the kickoff meeting.
let objectStore = db.createObjectStore(storeName, {keyPath:"names",autoIncrement:true});
objectStore.createIndex("name","name",{unique:true});
// Use transaction oncomplete to make sure the objectStore creation is
// finished before adding data into it.
objectStore.transaction.oncomplete = function(event) {
// Store values in the newly created objectStore.
let customerObjectStore = db.transaction(storeName, "readwrite").objectStore(storeName);
}
};}
function random (){
return (Math.floor((Math.random() * 10) + 1))
}
function addData(data,transaction){
return transaction.add(data)
}
function updateData(data,transaction){
let openCursor = transaction.index("name").openCursor();
openCursor.onsuccess= function(event){
let cursor = event.target.result;
if (cursor){
alert (cursor);
for(let I in data){
let item = data[I];
if(item.id === cursor.value.id){
let updateProperty = cursor.value;
updateProperty.minX = item.minX;
cursor.update(updateProperty);
cursor.continue()
}
}
}{alert("none")}
}
}
function deleteData(data,transaction){
}
</script>
</body>
</html>
不确定我是否理解清楚问题,但通常你会想要从对象存储中加载对象,修改每个对象的属性,然后将对象存储在对象存储中。有几种方法可以做到这一点。一种方法是使用 cursor.update,但我认为您根本不需要这样做。只需覆盖对象。
function storeThings(db, things, callback) {
var txn = db.transaction('store82', 'readwrite');
txn.oncomplete = callback;
var store = txn.objectStore('store82');
for(var thing of things) {
store.put(thing);
}
}
function open(callback) {
var request = indexedDB.open();
request.onsuccess = _ => callback(request.result);
}
var things = [{id:1}, {id:2}, {id:3}];
open(db => storeThings(db, things, _ => console.log('done')));
我正在使用 IDBObjectStore.prototype.put 来存储对象。 put 方法将创建或覆盖存储中的对象。当根据键路径找不到匹配的对象时,它将在商店中创建一个新对象。当找到匹配的对象时,它将替换商店中的现有对象。
在您的例子中,您使用 ssn 字符串作为键路径。因此,换句话说,如果找不到 ssn,它将创建新人,如果找到 ssn,它将覆盖人。您只需要确保 ssn 属性 是在您传递给 put 的每个人对象中定义的,否则 indexedDB 会报错。