در قسمت قبل متد 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 شوید مقدار زیر را مشاهده خواهید کرد:
بنابراین کد ما به شکل صحیح کار می کند. در مرحله ی بعد باید کتاب های دریافت شده را در جدول برنامه نشان دهیم بنابراین به سراغ 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 می کنیم تا بروزرسانی شود.
به شما تبریک می گویم، پروژه ی ما کامل شده است! شما می توانید سورس کد کامل این پروژه را از این لینک دانلود کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.