IndexedDB در استروئیدها با استفاده از Dexie.js

این مقاله در ابتدا در وبلاگ من با نکات برجسته خط قطعه کد و غیره منتشر شد. می توانید آن را بررسی کنید.
IndexedDB چیست؟
IndexedDB یک پایگاه داده NoSQL در سمت کلاینت است که به برنامه های وب اجازه ذخیره و بازیابی داده ها را می دهد. از آنجایی که داده ها به صورت محلی در مرورگر ذخیره می شوند، حتی به صورت آفلاین نیز در دسترس هستند.
مزیت اصلی indexedDB نسبت به ذخیرهسازی محلی این بود که حتی میتوانستیم فایلها و حبابها (مانند تصاویر، ویدیوها و غیره) را همراه با اشیا ذخیره کنیم.
Dexie.js
کار با API سطح پایین indexedDB به طور مستقیم کار بسیار زیادی است. می توانید این مقاله را در مورد MDN در مورد استفاده مستقیم از indexedDB API بررسی کنید.
برای آسانتر کردن کارها، Dexie.js یک فرآیند ساده و ساده برای ایجاد پایگاههای داده، ذخیره دادهها، بهروزرسانی دادهها و انتقال پایگاه داده و غیره در بالای indexedDB ارائه میکند.
با استفاده از Dexie.js
ما برای درک اصول اولیه dexie.js، مانند ایجاد پایگاه داده و انجام عملیات CRUD، یک برنامه ساده برای انجام کار خواهیم ساخت.
راه اندازی برنامه
بیایید ایجاد کنیم index.html
فایل با محتوای زیر
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
</head>
<body>
<div class="content">
<ul id="todoList">
</ul>
</div>
<div>
<form id="addTodoForm" class="column form">
<div class="field">
<label class="label" for="todo">Todo</label>
<div class="control">
<input required class="input" name="todo" id="todo" type="text" placeholder="Todo">
</div>
</div>
<div class="field is-grouped">
<div class="control">
<button class="button is-link">Create todo</button>
</div>
</div>
</form>
</div>
</body>
</html>
اکنون فایل html را با استفاده از سرور HTTP انتخابی خود باز کنید. من از پسوند Live Server VS Code استفاده می کنم. شما چیزی شبیه به این را خواهید دید.
برای استایل، از Bulma CSS استفاده می کنیم. Todos با تایپ کردن در کادر ورودی اضافه می شود. در حال حاضر هیچ چیز کار نمی کند، زیرا ما هنوز باید جاوا اسکریپت را اضافه کنیم.
افزودن Dexie.js
یک فایل جاوا اسکریپت با نام ایجاد کنید main.js,
جایی که منطق تجاری برنامه را می نویسیم. ما از یک باندلر ماژول مانند webpack یا parcel.js برای ساده نگه داشتن کارها استفاده نخواهیم کرد. در عوض، ما قصد داریم استفاده کنیم Dexie
مستقیماً از CDN
حالا هر دو را در فایل html قرار دهید.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
</head>
<body>
<div class="content">
<ul id="todoList">
</ul>
</div>
<div>
<form id="addTodoForm" class="column form">
<div class="field">
<label class="label" for="todo">Todo</label>
<div class="control">
<input required class="input" name="todo" id="todo" type="text" placeholder="Todo">
</div>
</div>
<div class="field is-grouped">
<div class="control">
<button class="button is-link">Create todo</button>
</div>
</div>
</form>
</div>
<script src="https://unpkg.com/dexie/dist/dexie.js"></script>
<script src="./main.js"></script>
</body>
</html>
گرفتن ورودی کاربر
که در main.js,
ما شنوندگان رویداد را اضافه خواهیم کرد تا ورودی کاربر را ضبط کنیم.
const formElement = document.getElementById('addTodoForm');
const todoInput = document.getElementById('todo');
const todoList = document.getElementById('todoList');
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const todoName = todoInput.value;
console.log('Todo to be created', todoName)
todoInput.value = '' // reset input
});
-
formElement
– فرمی که در آن ورودی های کاربر را برای ایجاد TODO دریافت می کنیم -
todoInput
– ورودی که در آن کاربر وارد todo می شود -
todoList
– عنصری که در آن می خواهیم همه کارها را فهرست کنیم
در حال حاضر، با ارسال فرم، ما در حال ورود به کنسول هستیم. اما در حالت ایدهآل، چیزی که میخواهیم این است که to-do را در پایگاه داده ایجاد کنیم و آن را در UI نشان دهیم. ما قصد داریم از Dexie.js برای آن استفاده کنیم.
ایجاد پایگاه داده و جداول
ما می توانیم با استفاده از dexie.js یک پایگاه داده indexedDB ایجاد کنیم.
const db = new Dexie('databaseName')
می توانید جداول را با استفاده از db
نمونه، مثال stores
روش را با ارسال یک شی که در آن نام جدول کلید است و مقادیر ستون هایی هستند که با کاما از هم جدا شده اند.
db.version(1).stores({
tableOne: `++id, col3, col3`,
tableTwo: `++id, col3, col3`,
});
می توانید چندین نسخه از پایگاه داده را با شماره نسخه نگهداری کنید. این شبیه به نسخه indexedDB است.
هنگام اعلام ستون ها
- اولین مورد کلید اصلی خواهد بود.
-
++
پیشوند آن را به یک کلید اولیه با افزایش خودکار تبدیل می کند -
&
پیشوند آن را به یک ستون منحصر به فرد تبدیل می کند
بیایید یک پایگاه داده به نام ایجاد کنیم TodoDatabase
ما todos را در ذخیره می کنیم todo
جدول با ستون های زیر
-
id
– کلید اصلی -
name
– نام کار -
completed
– وضعیت Todo
const db = new Dexie('TodoDatabase');
db.version(1).stores({
todo: `++id, name, completed`,
});
const formElement = document.getElementById('addTodoForm');
const todoInput = document.getElementById('todo');
const todoList = document.getElementById('todoList');
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const todoName = todoInput.value;
console.log('Todo to be created', todoName)
// reset input
todoInput.value = ''
});
درج در پایگاه داده
بیایید todos را وارد کنید todo
جدول. با استفاده از () Table.add اشیاء را در جدول وارد کنید.
const db = new Dexie('TodoDatabase');
db.version(1).stores({
todo: `++id, name, completed`,
});
const formElement = document.getElementById('addTodoForm');
const todoInput = document.getElementById('todo');
const todoList = document.getElementById('todoList');
async function createTodo(todoName) {
try {
await db.todo.add({
name: todoName,
completed: false,
});
} catch (error) {
console.error(error)
}
}
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const todoName = todoInput.value;
createTodo(todoName);
// reset input
todoInput.value = ''
});
با ارسال فرم، کار را به آن ارسال می کنیم createTodo
تابع.
createTodo
تابع کار جدید را با استفاده از درج می کند Table.add()
روش. ما نیازی به پاس کردن نداریم id
همانطور که به طور خودکار افزایش می یابد.
حال اگر todos را اضافه کنید، todoهای جدید در آن درج خواهند شد todo
جدول. می توانید آنها را در ابزار توسعه بررسی کنید.
نمایش کارهای ایجاد شده در UI
حتی اگر کارها در حال ایجاد هستند، در رابط کاربری قابل مشاهده نیستند. برای ردیابی تغییرات هنگام افزودن، بهروزرسانی یا حذف و نمایش آنها در رابط کاربری، از liveQuery استفاده میکنیم.
اگر بگذرید liveQuery
، یک پرس و جو پایگاه داده مانند Table.where
یا Table.toArray
. هر زمان که تغییرات پایگاه داده مانند ایجاد، به روز رسانی یا حذف بر نتیجه پرس و جو شما تأثیر بگذارد، فراخوانی ارسال شده فراخوانی می شود و نتیجه (مقدار برگشتی) توسط قابل مشاهده منتشر می شود.
مانند یک شنونده رویداد به این موضوع فکر کنید.
ایجاد یک to-do قابل مشاهده که ما میتوانیم در آن مشترک شویم و هر زمان که کارها اضافه یا بهروزرسانی میشوند، UI را بهروزرسانی کنیم.
const todoObservable = Dexie.liveQuery(() => db.todo.toArray());
اشتراک در قابل مشاهده
const db = new Dexie('TodoDatabase');
db.version(1).stores({
todo: `++id, name, completed`,
});
const formElement = document.getElementById('addTodoForm');
const todoInput = document.getElementById('todo');
const todoList = document.getElementById('todoList');
async function createTodo(todoName) {
try {
await db.todo.add({
name: todoName,
completed: false,
});
} catch (error) {
console.error(error)
}
}
const todoObservable = Dexie.liveQuery(() => db.todo.toArray());
todoObservable.subscribe({
next: (result) => {
// first remove existing items
todoList.innerHTML = ''
result.forEach((todo) => {
let newTodo = document.createElement('li');
newTodo.dataset.id = todo.id;
newTodo.dataset.completed = todo.completed;
newTodo.innerText = todo.name;
console.log(newTodo);
todoList.appendChild(newTodo);
});
},
error: (error) => console.error(error),
});
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const todoName = todoInput.value;
createTodo(todoName);
// reset input
todoInput.value = ''
});
هنگام اشتراک در مشاهده پذیر، باید آن را پاس کنیم next
و error
پاسخ به تماس
-
next
– هر زمان که تماس برگشتی از اجرا شودliveQuery
نتیجه به منتقل خواهد شدnext
-
error
– برای رسیدگی به خطاها برای پاسخ به تماس و غیره
در مورد ما، ما روی همه کارها حلقه می زنیم و آنها را با استفاده از UI ارائه می کنیم Array.forEach
. اکنون هر زمان که میخواهید کار جدید را اضافه کنید، در UI ارائه میشود
به روز رسانی داده ها در پایگاه داده
برای علامت زدن کار به عنوان کامل، کاربر روی مورد کار کلیک می کند و سپس وضعیت تکمیل شده به تغییر می یابد. true
و بالعکس. ما می توانیم به روز رسانی کنیم completed
ستون برای کارهای انجام شده با استفاده از Table.update(). Table.update()
مقدار کلید اولیه را به عنوان آرگومان اول و داده هایی که باید به روز شوند را به عنوان آرگومان دوم می پذیرد.
db.todo.update(primaryKeyValue, dataToBeUpdated)
بیایید یک تابع به نام ایجاد کنیم toggleTodoCompleteStatus
که وضعیت انجام شده را تغییر می دهد.
const db = new Dexie('TodoDatabase');
db.version(1).stores({
todo: `++id, name, completed`,
});
const formElement = document.getElementById('addTodoForm');
const todoInput = document.getElementById('todo');
const todoList = document.getElementById('todoList');
async function createTodo(todoName) {
try {
await db.todo.add({
name: todoName,
completed: false,
});
} catch (error) {
console.error(error)
}
}
const todoObservable = Dexie.liveQuery(() => db.todo.toArray());
async function toggleTodoCompleteStatus(event) {
const { id, completed } = event.target.dataset;
try {
const isUpdated = await db.todo.update(parseInt(id), {
completed: !JSON.parse(completed), // to convert 'false` -> false etc
});
if (!isUpdated) {
throw new Error('Error updating');
}
} catch (error) {
console.error(error)
}
}
todoObservable.subscribe({
next: (result) => {
// first remove existing items
todoList.innerHTML = ''
result.forEach((todo) => {
let newTodo = document.createElement('li');
newTodo.dataset.id = todo.id;
newTodo.dataset.completed = todo.completed;
newTodo.innerText = todo.name;
newTodo.onclick = toggleTodoCompleteStatus;
console.log(newTodo);
todoList.appendChild(newTodo);
});
},
error: (error) => console.error(error),
});
formElement.addEventListener('submit', (e) => {
e.preventDefault();
const todoName = todoInput.value;
createTodo(todoName);
// reset input
todoInput.value = ''
});
ما همچنین این را به onclick
روش مستقیم را toggleTodoCompleteStatus
عنصر HTML لیست کارها و وضعیت تکمیل شده را از ویژگی مجموعه داده عنصر HTML می گیرد.
همانطور که قبلاً مشترک شده ایم، همه تغییرات بلافاصله در UI منعکس می شوند todoObservable
ورزش
تا به حال، ما یاد گرفتیم که چگونه یک پایگاه داده ایجاد کنیم، یک جدول ایجاد کنیم، داده ها را اضافه کنیم و داده ها را به روز کنیم. به عنوان یک تمرین کوچک، قابلیت حذف todo را اضافه کنید که با یافتن روشهای مناسب از dexiejs docs، مورد todo را از پایگاه داده حذف میکند.
کد نهایی