برنامه لیست کتاب: اضافه کردن پروژه به Local Storage (قسمت 2)

اضافه کردن پروژه به Local Storage (قسمت 2)

اضافه کردن پروژه به Local Storage (قسمت 2)

در قسمت قبل متد getBooks را کدنویسی کردیم تا برای هر بار دریافت کتاب ها از LocalStorage نیاز به نوشتن چند باره ی کدها نباشد. حالا که getBooks را داریم می توانیم به addBook برگردیم و آن را کدنویسی کنیم:

static addBook(book) {
    const books = Store.getBooks();

    books.push(book);

    localStorage.setItem('books', JSON.stringify(books));
}

در اینجا کتاب های داخل LocalStorage را دریافت کرده و درون یک متغیر جدید به نام books قرار می دهیم (از const استفاده شده چرا که قرار نیست این متغیر بعدا تغییر کند). سپس کتاب جدیدی را که به صورت پارامتر addBook دریافت کرده ایم به این متغیر اضافه می کنیم. همانطور که قبلا گفتم LocalStorage داده ها را فقط و فقط به صورت رشته ذخیره می کند بنابراین اگر داده های رشته ای داشته باشیم آن ها را به سادگی و به شکل زیر در آن ثبت می کنیم:

window.localStorage.setItem('name', 'Obaseki Nosa');

اما اگر داده های ما آرایه یا شیء باشند باید آن ها را به رشته تبدیل کنیم. برای انجام این کار از متد JSON.stringify استفاده می کنیم:

const person = {
    name: "Obaseki Nosa",
    location: "Lagos",
}

window.localStorage.setItem('user', JSON.stringify(person));

از طرفی books یک آرایه است بنابراین قبل از ارسال آن به setItem آن را به صورت رشته در آورده ایم. اگر در این مرحله به مرورگر بروید و یک کتاب را ثبت کنید هیچ اتفاق خاصی نمی افتد (کتاب مثل همیشه ثبت می شود) اما اگر از dev tools (معمولا کلید f12) مرورگر خود وارد قسمت Application و سپس Local Storage شوید مقدار زیر را مشاهده خواهید کرد:

کتاب ثبت شده توسط ما درون LocalStorage قرار گرفته است.
کتاب ثبت شده توسط ما درون LocalStorage قرار گرفته است.

بنابراین کد ما به شکل صحیح کار می کند. در مرحله ی بعد باید کتاب های دریافت شده را در جدول برنامه نشان دهیم بنابراین به سراغ displayBooks می رویم و آن را به شکل زیر کدنویسی می کنیم:

static displayBooks() {
    const books = Store.getBooks();

    books.forEach(function (book) {
        const ui = new UI;

        // Add book to UI
        ui.addBookToList(book);
    });
}

در ابتدا مثل همیشه کتاب ها را دریافت کرده ایم، سپس از یک حلقه ی forEach استفاده کرده ایم تا بین کتاب های مختلف گردش کنیم و تک تک آن ها را به LocalStorage اضافه کنیم. فرآیند اضافه کردن کتاب به جدول را قبلا در متدی به نام addBookToList برنامه نویسی کرده بودیم که متعلق به کلاس UI بود. به همین دلیل برای استفاده از آن ابتدا یک شیء از کلاس UI ساخته ایم و کتاب مورد نظرمان را به آن پاس داده ایم تا آن را در جدول قرار دهد.

در حال حاضر این متد هیچ جا فراخوانی نمی شود بنابراین استفاده هم نخواهد شد. برای حل این مشکل از کلاس Store خارج شده و یک event-listener جدید می نویسیم. من این event-listener جدید را بعد از کلاس Store قرار می دهم:

// DOM Load Event
document.addEventListener('DOMContentLoaded', Store.displayBooks);

به سادگی گفته ایم زمانی که محتوای DOM بارگذاری شد، متد displayBooks را فراخوانی کن تا کتاب های ما نمایش داده شوند. در حال حاضر می توانید به مرورگر مراجعه کرده و کد بالا را تست کنید؛ کتاب های که ثبت کرده باشید باید برایتان نمایش داده شوند و با refresh صفحه از بین نروند.

در مرحله ی بعد به سراغ متد removeBook می رویم. کار ما در این قسمت کمی پیچیده تر است چرا که هیچ id خاصی برای حذف یک مورد خاص از بین چندین مورد نداریم بنابراین باید از مقداری استفاده کنیم که به هیچ عنوان تکرار نشود. از آنجایی که ISBN یک عدد یکتا و خاص است من از همین عدد برای شناسایی مورد خاص استفاده می کنم. اگر یادتان باشد فرآیند حذف کتاب ها از جدول را به صورت زیر کدنویسی کرده بودیم:

// Event Listener for delete
document.getElementById('book-list').addEventListener('click', function(e){

  // Instantiate UI
  const ui = new UI();

  // Delete book
  ui.deleteBook(e.target);

  // Show message
  ui.showAlert('Book Removed!', 'success');

  e.preventDefault();
});

من می خواهم در این قسمت متد removeBook را صدا بزنم و بگویم:

// Event Listener for delete
document.getElementById('book-list').addEventListener('click', function(e){

  // Instantiate UI
  const ui = new UI();

  // Delete book
  ui.deleteBook(e.target);

  // Remove from LS
  Store.removeBook(e.target.parentElement.previousElementSibling.textContent);

  // Show message
  ui.showAlert('Book Removed!', 'success');

  e.preventDefault();
});

همانطور که گفتم قرار است عدد ISBN را به عنوان کلید یکتا به removeBook پاس بدهیم تا بداند کدام کتاب و ردیف را از جدول حذف کند. مقدار e.target برابر همان حرف X (کلید حذف ردیف یا همان تگ <a>) است و عنصر پدر آن (parentElement) همان تگ <td> می باشد. به ساختار HTML ردیف ها نگاه کنید:

ساختار ردیف های جدول در برنامه ی ما
ساختار ردیف های جدول در برنامه ی ما

شماره ی ISBN عنصر قبل از تگ <a> می باشد بنابراین می توانیم از previousElementSibling استفاده کنیم تا عنصر قبلی را بگیریم (رابطه ی برادری) که کل تگ را به ما می دهد و سپس با استفاده از textContent فقط مقدار درون تگ (عدد ISBN) را دریافت می کنیم.

حالا به متد removeBook برمی گردیم و می گوییم:

static removeBook(isbn) {
  const books = Store.getBooks();

  books.forEach(function(book, index){
   if(book.isbn === isbn) {
    books.splice(index, 1);
   }
  });

  localStorage.setItem('books', JSON.stringify(books));
}

مثل همیشه در ابتدای کار کتاب ها را دریافت کرده ایم و سپس با استفاده از یک حلقه ی forEach برای گردش بین آن ها استفاده کرده ایم. پارامتر book (در شرط if) تک تک اعضای books است که از LocalStorage دریافت کرده ایم و به صورت خودکار توسط جاوا اسکریپت پاس داده می شود. درون forEach یک شرط if داریم که می گوید اگر isbn موجود در متغیر book (یعنی هر کدام از کتاب ها) برابر با isbn پاس داده شده به متد removeBook است باید آن را حذف کنیم. در نهایت LocalStorage را دوباره set می کنیم تا بروزرسانی شود.

به شما تبریک می گویم، پروژه ی ما کامل شده است! شما می توانید سورس کد کامل این پروژه را از این لینک دانلود کنید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پروژه‌های مدرن جاوا اسکریپت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.