تا اینجای کار برنامه ما به خوبی کار می کند و در ادامه آن می خواهیم قابلیت حذف پست ها را نیز به آن اضافه کنیم. انجام این کار بسیار ساده است بنابراین متد مربوط به آن را برایتان قرار می دهم. شما باید وارد فایل App.js شده و به شکل زیر کدهای من را تکرار کنید. ابتدا یک event-listener می خواهیم:
// Listen for add post document.querySelector('.post-submit').addEventListener('click', submitPost); // Listen for delete document.querySelector('#posts').addEventListener('click', deletePost);
یعنی هنگامی که روی آیدی posts کلیک شد تابعی به نام deletePost را اجرا کن. از آنجا که پست ها به صورت پویا اضافه خواهند شد نمی توانیم یک id خاص را هدف گرفته، بلکه باید posts را هدف بگیریم (مسئله event delegation در جاوا اسکریپت).
حالا باید متدمان را تعریف کنیم:
// Delete Post function deletePost(e) { e.preventDefault(); if (e.target.parentElement.classList.contains('delete')) { const id = e.target.parentElement.dataset.id; if (confirm('Are you sure?')) { http .delete(`http://localhost:3000/posts/${id}`) .then(data => { ui.showAlert('Post Removed', 'alert alert-success'); getPosts(); }) .catch(err => console.log(err)); } } }
در همان ابتدا e.preventDefault را صدا می زنیم تا رفتار پیش فرض عنصر را کنترل و مهار کنیم. سپس گفته ایم اگر تگِ پدرِ عنصری که روی آن کلیک کرده ایم دارای کلاس delete بود، یک ثابت به نام id بساز. این id باید id همان عنصری باشد که روی آن کلیک شده است اما چطور می توانیم آن را بگیریم؟ در کد بالا من به دنبال dataset ای به نام id گشته ام و آن را برابر id قرار داده ام. چرا؟ اگر به متد showPosts در فایل ui.js بروید، قسمتی به شکل زیر را داریم:
<a href="#" class="delete card-link" data-id="${post.id}">
از شما انتظار می رود که با ساختار های data-x در زبان HTML آشنا باشید (در این attribute ها می توانیم خصوصیات خودمان را تعریف کنیم، یعنی به جای x هر مقدار دلخواهی را بگذاریم). کد attribute دارای id تعریف شده توسط ما بود. در زبان جاوا اسکریپت می توانیم از dataset کمک بگیریم تا به چنین مقادیری دسترسی داشته باشیم. سپس با استفاده از پنجره confirm از کاربر می پرسیم که آیا از تصمیم خود اطمینان دارد؟ در صورتی که تایید کند با ماژول http درخواست delete خود را ارسال می کنیم. همچنین یک alert نشان می دهیم که کاربر بداند پست با موفقیت حذف شده است و دوباره getPosts را صدا می زنیم تا لیست پست ها به روز رسانی شود.
برای ویرایش پست ها نیز با یک event-listener ساده شروع می کنیم:
// Listen for delete document.querySelector('#posts').addEventListener('click', deletePost); // Listen for edit state document.querySelector('#posts').addEventListener('click', enableEdit);
باز هم می گویم: از آنجایی که پست ها به صورت پویا و بعد از اجرا شدن کدهای ما اجرا می شوند، نمی توانیم id خاصی را هدف بگیریم بنابراین باید کل posts را هدف قرار دهیم. این همان مسئله event delegation است که در همین دوره چندین بار درباره اش صحبت کرده ایم. حالا باید متد enableEdit را تعریف کنیم:
// Enable Edit State function enableEdit(e) { if(e.target.parentElement.classList.contains('edit')) { const id = e.target.parentElement.dataset.id; const title = e.target.parentElement.previousElementSibling.previousElementSibling.textContent; const body = e.target.parentElement.previousElementSibling.textContent; } e.preventDefault(); }
اگر به این کد دقت کنید، متوجه می شوید که منطق آن دقیقا مانند منطق Delete است. ابتدا preventDefault کرده ایم تا رفتار پیش فرض تگ <a> را کنترل کنیم. سپس گفته ایم اگر target ما دارای تگ پدری بود که کلاس edit داشته است باید it و title و body آن را بگیریم. برای گرفتن id از همان روش حذف پست ها عمل کرده ایم (استفاده از تگ های Dataset) و برای گرفتن title و body نیز بر اساس ساختار HTML خود پیش رفته ایم تا به عنصر مورد نظرمان برسیم. مثلا target.parentElement به ما تگ <a> را می دهد و سپس دو بار می گوییم previousElementSibling را صدا می زنیم تا به دو تگِ برادریِ بالاتر منتقل شویم. در نهایت با textContetnt متن آن تگ را استخراج کرده ایم.
در قدم بعدی باید شیء ای تعریف کرده و تمام این موارد را در آن قرار دهیم:
// Enable Edit State function enableEdit(e) { if(e.target.parentElement.classList.contains('edit')) { const id = e.target.parentElement.dataset.id; const title = e.target.parentElement.previousElementSibling.previousElementSibling.textContent; const body = e.target.parentElement.previousElementSibling.textContent; const data = { id, title, body } // Fill form with current post ui.fillForm(data); } e.preventDefault(); }
من این مقادیر را درون شیء data قرار داده ام و سپس متدی را به نام fillForm صدا زده ام. این متد هنوز تعریف نشده است اما قرار است مقادیر من را گرفته و درون فیلد های فرم قرار دهد تا کاربر آن ها را ویرایش کند. حالا برای تعریف کردن fillForm به فایل ui.js می رویم و این متد را تعریف می کنیم:
// Clear all fields clearFields() { this.titleInput.value = ''; this.bodyInput.value = ''; } // Fill form to edit fillForm(data) { this.titleInput.value = data.title; this.bodyInput.value = data.body; this.idInput.value = data.id; }
اگر یادتان باشد درون فایل index.html ما یک فیلد مخفی id داشتیم:
<input type="hidden" id="id" value="">
من آیدی را روی این id تنظیم کرده ام تا هنگام ثبت دوباره این مقدار توسط کاربر، بتوانیم id را حفظ کنیم. در قسمت بعد باید بتوانیم این فرآیند را تکمیل کرده و کل این پروژه را تمام کنیم. همچنین چند ویرایش جزئی را نیز انجام خواهیم داد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.