javascript - 比较 IndexedDB 中两个不同存储的值
问题描述
我有两个数据结构:
- 任务:taskID(自动递增)、title、status、dueDate、description
- 标签:tagID、tagName、tagColor、textColor、taskID
我正在尝试比较它们的 taskID 值,以便以后能够将单个任务与多个标签相关联。我编写了两个函数,getTags() 和 getTasks()。我已经设法遍历它们,获取两个商店中的所有对象,但是,我不太确定如何检查这两个值是否匹配。
function connectToDB() {
window.webkitIndexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
//check for support
if(!window.indexedDB) {
alert("Your browser do not support indexedDB. Please update you browser.")
}
//open database "KanbanDatabase" version 9.
//db = database, tx = transaction, store = store data, index = index (seach data).
let request = window.indexedDB.open("KanbanDatabase", 9),
db,
tx,
store,
index;
//when creating a new databse, a store(structure) must be added
request.onupgradeneeded = function(e) {
let db = request.result,
//tasks
tasksStore = db.createObjectStore("tasksStore",{
keyPath: "taskID", autoIncrement: true
}),
tasksIndex = tasksStore.createIndex("status", "status", {
unique: false
}),
//tags
tagsStore = db.createObjectStore("tagsStore", {
keyPath: "tagID", autoIncrement: true
}),
tagsIndex = tagsStore.createIndex("tagID", "tagID", {
unique: true
});
};
//open database will return response.
//error handler:
request.onerror = function(e) {
console.error("There was an error opening the database: " + e.target.errorCode);
};
//success handler:
request.onsuccess = function(e) {
console.log("Successfully connected to DB")
db = request.result;
//tasks
tasksTx = db.transaction("tasksStore", "readwrite");
tasksStore = tasksTx.objectStore("tasksStore");
tasksIndex = tasksStore.index("status");
//tags
tagsTx = db.transaction("tagsStore", "readwrite");
tagsStore = tagsTx.objectStore("tagsStore");
tagsIndex = tagsStore.index("tagID");
db.onerror = function(e) {
console.error("ERROR " + e.target.errorCode);
}
function tagsToTasks() {
let amountOfTasks = tasksIndex.count();
let amountOfTags = tagsIndex.count();
function getTasks() {
for (var i = 1; i < amountOfTasks.result+1; i++) {
let getTasks = tasksStore.get(i);
getTasks.onerror = function() {
console.error("There was an error looping through the tasks");
}
getTasks.onsuccess = function() {
console.log(getTasks.result.taskID)
}
}
}
function getTags() {
for (var j = 1; j < amountOfTags.result+1; j++) {
let getTags = tagsStore.get(j);
getTags.onerror = function() {
console.error("There was en error looping through the tags");
}
getTags.onsuccess = function() {
let result = getTags.result.taskID;
return result;
}
}
}
function compareID() {
//what to do?
}
amountOfTasks.onerror = function() {
console.error("There was an error finding the amount of tasks");
}
amountOfTasks.onsuccess = function() {
getTasks();
}
amountOfTags.onerror = function() {
console.error("There was an error finding the amount of tags");
}
amountOfTags.onsuccess = function() {
getTags();
}
}
//fire functions
tagsToTasks();
listTasks();
//close DB conection once transaction is complete.
tasksTx.oncomplete = function() {
db.close();
}
tagsTx.oncomplete = function() {
db.close();
}
}
}
编辑:澄清:我需要比较两个不同商店的两个值。问题始于 tagsToTasks() 函数;如何将 getTags() 函数中的 getTags.result.taskID 返回的值与 getTasks() 函数中的 getTasks.result.taskID 进行比较?
解决方案
第一个错误在这里。
window.webkitIndexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;`
您将其分配给window.webkitIndexedDb
但window.indexedDb
在下一行检查。
我建议使用本地 const 而不是尝试覆盖全局变量。
像这样,
const indexedDb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if (!indexedDb) return ....
接下来,您可以使用cursor
或getAll
方法来检索所有对象。此外,您不能从onSuccess
事件处理程序返回任务,您需要从父范围为其分配一个变量。像这样,
let tasks = [];
tasksStore.getAll().onsuccess = function(event) {
tasks = event.target.result
attachTags(tasks);
};
function attachTags(tasks) {
tags.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
const task = tasks.find(t => t.taskId == cursor.value.taskId);
if (!task.tags) task.tags = []
task.tags.push(cursor.value) ;
cursor.continue();
}
else {
return;
}
};
}
看起来你必须经历回调地狱才能做到这一点。我正在使用该方法使用atfind
指向的当前标记的 taskId 来选择任务,然后为该任务创建一个标记数组并将标记推入其中。查看您的数据模型,我假设您希望通过 taskId 外键将每个标签与相关任务相关联。cursor
cursor.value
您设置事物的方式的问题在于 indexedDB 使用回调来返回值,而您的代码中没有任何地方保存这些值并将其传递给需要它们的函数。您编写的回调基本上对它们收到的值没有任何作用。您不能从回调中返回值,因为回调是由 API 调用的,而不是您的代码。您需要在回调外部为变量赋值或在回调内部进行处理。回调彼此异步执行,因此无法保证您的代码将按照您编写的顺序执行,这让您别无选择,只能从当前回调设置下一个回调,这被称为回调地狱. Promise 有助于缓解这种情况,所以如果你打算在生产中使用它, https://github.com/jakearchibald/idb公开了一个更可用的 Api。
推荐阅读
- node.js - 在 npm install 上创建伪 node_modules 文件夹
- mysql - MySQL - 在同一个选择查询中从表中检索不同的数据
- java - 了解 Java 泛型
- c# - 仅在更新时防止默认值?
- c++ - 通过模板函数调用未知类型的方法
- csv - 如何让海龟在 NETLOGO 中导入 csv.file 的值
- shared-memory - 如何在 Ada 中使用 Linux 将任意字符串写入然后读取到共享内存?
- python - python中的索引数组(摩尔社区)
- c# - c# WinForms 在子窗体中打开颜色对话框
- marklogic - Marklogic 中的可搜索表达式