برنامه نویسی

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 استفاده می کنم. شما چیزی شبیه به این را خواهید دید.

صفحه دیگ بخار HTML

برای استایل، از 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 جدول. می توانید آنها را در ابزار توسعه بررسی کنید.

IndexedDB با استفاده از dexie js در ابزارهای توسعه دهنده

نمایش کارهای ایجاد شده در 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 را از پایگاه داده حذف می‌کند.

کد نهایی

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا