تا این قسمت از کار می توانیم آیتم های غذایی را از کاربر دریافت کرده و در UI نمایش دهیم اما هنوز محاسبه تعداد کل کالری ها باقی مانده است. در حال حاضر اگر 10 آیتم هم اضافه کنید، تعداد کل کالری ها روی عدد صفر باقی می ماند که ما باید آن را تصحیح کنیم. برای شروع به کنترلر App بروید و دقیقا قبل از اینکه فیلدهای input را خالی کنیم، متد آن را بنویسید. اولین قدم دریافت تعداد کل کالری ها است تا آن مقدار را با کالری آیتم جدید جمع بزنیم بنابراین:
// Add item submit const itemAddSubmit = function(e){ // Get form input from UI Controller const input = UICtrl.getItemInput(); // Check for name and calorie input if(input.name !== '' && input.calories !== ''){ // Add item const newItem = ItemCtrl.addItem(input.name, input.calories); // Add item to UI list UICtrl.addListItem(newItem); // Get total calories const totalCalories = ItemCtrl.getTotalCalories(); // Clear fields UICtrl.clearInput(); } e.preventDefault(); }
تابع getTotalCalories هنوز تعریف نشده است بنابراین باید آن را تعریف کنیم. به نظر من تعریف کردن این متد درون کنترلر item مناسب است اما نحوه محاسبه کالری کل چگونه خواهد بود؟ روش کاری ما بدین شکل است که بین آیتم ها گردش می کنیم و مقدار کالری هر کدام از آن ها را با مقدار کالری قبلی جمع می زنیم:
// بقیهکدها // getTotalCalories: function(){ let total = 0; // Loop through items and add cals data.items.forEach(function(item){ total += item.calories; }); // Set total cal in data structure data.totalCalories = total; // Return total return data.totalCalories; }, logData: function(){ return data; } } })();
در ابتدا متغیری به نام total تعریف کرده و مقدار آن را برابر صفر می گذاریم. سپس از شیء data (همان data structure ما) به آرایهitems دسترسی پیدا کرده و روی آن ها یک حلقه forEach زده ایم. این حلقه بین تمام آیتم های آرایهitems گردش کرده و item.calories (مقدار کالری هر آیتم غذایی) را به total اضافه می کند. توجه کنید که از علامت مساوی استفاده نکرده ایم بلکه از علامت =+ استفاده کرده ایم تا مقادیر قبلی حذف نشوند. در مرحلهبعد خصوصیت totalCalories در شیء data را روی total تنظیم می کنیم و آن را برمی گردانیم. برگرداندن این مقدار برای این است که اگر بعدا بخواهیم به این مقدار در تابعی دیگر دسترسی داشته باشیم، بدون زحمت این کار را انجام دهیم.
حالا به کنترلر App برمی گردیم تا از متدی دیگر برای نمایش کالری کل استفاده کنیم. در حال حاضر فقط کالری کل را محاسبه کرده ایم:
// Add item submit const itemAddSubmit = function(e){ // Get form input from UI Controller const input = UICtrl.getItemInput(); // Check for name and calorie input if(input.name !== '' && input.calories !== ''){ // Add item const newItem = ItemCtrl.addItem(input.name, input.calories); // Add item to UI list UICtrl.addListItem(newItem); // Get total calories const totalCalories = ItemCtrl.getTotalCalories(); // Add total calories to UI UICtrl.showTotalCalories(totalCalories); // Clear fields UICtrl.clearInput(); } e.preventDefault(); }
showTotalCalories متدی خواهد بود که تعداد کل کالری را گرفته و آن را در UI برای کاربر نمایش می دهد. چنین متدی را هنوز تعریف نکرده ایم بنابراین به کنترلر UI می رویم تا آن را تعریف کنیم:
// بقیهکدها // showTotalCalories: function(totalCalories){ document.querySelector(UISelectors.totalCalories).textContent = totalCalories; }, getSelectors: function(){ return UISelectors; } } })();
همانطور که می بینید محتوای total calories را روی عدد محاسبه شده قرار داده ایم. من در کد بالا از یک سلکتور به نام UISelectors.totalCalories استفاده کرده ام بنابراین باید آن را نیز در شیء UISelectors تعریف کنیم:
// UI Controller const UICtrl = (function(){ const UISelectors = { itemList: '#item-list', addBtn: '.add-btn', itemNameInput: '#item-name', itemCaloriesInput: '#item-calories', totalCalories: '.total-calories' } // بقیهکدها //
اگر یادتان باشد کلاس total-calories مخصوص قسمت total calories بود. می توانید آن را درون فایل index.html پیدا کنید. حالا برنامه به خوبی کار می کند اما یک نکته باقی مانده است. از آنجایی که بعدا می خواهیم داده های کاربر را درون local storage ثبت کنیم دیگر نمی توان گفت با هر بار شروع برنامه تعداد کالری ها صفر خواهد بود. در وضعیت فعلی برنامه، با هر بار refresh صفحه تمام آیتم ها حذف می شوند بنابراین فعلا کدها مشکلی ندارند و با هر بار اجرای برنامه باید تعداد کالری ها کل ما برابر صفر باشد اما اگر از local storage استفاده کنیم و کاربر 4 آیتم غذایی را با تعداد کل کالری 600 ثبت کرده باشد، با refresh شدن صفحه این آیتم ها از بین نمی روند. بنابراین حتی با بارگذاری اولیه برنامه تعداد کالری ها لزوما صفر نیست مگر اینکه خود کاربر آیتم ها را حذف کند. به همین دلیل و برای جلوگیری از مشکلات آینده تعداد کالری ها را در init نیز محاسبه می کنیم:
// Public methods return { init: function(){ // Fetch items from data structure const items = ItemCtrl.getItems(); // Check if any items if(items.length === 0){ UICtrl.hideList(); } else { // Populate list with items UICtrl.populateItemList(items); } // Get total calories const totalCalories = ItemCtrl.getTotalCalories(); // Add total calories to UI UICtrl.showTotalCalories(totalCalories); // Load event listeners loadEventListeners(); } }
با این کار مطمئن می شویم که تعداد کالری کل همیشه به درستی محاسبه خواهد شد و از بروز خطا جلوگیری می شود. البته در آینده زمانی که به جلسه local storage برسیم این کدها را ویرایش کرده و مفصلا توضیح خواهیم داد. در جلسه بعد باید روی عملکرد دکمهedit (آیکون مداد) کار کنیم. در حال حاضر کلیک روی این آیکون هیچ کاری انجام نمی دهد اما در جلسه بعد کاری خواهیم کرد که با کلیک روی آن دکمه Add Meal مخفی شده و گزینه های ویرایش به جای آن ظاهر شوند. اگر یادتان باشد دکمه های edit را در جلسه اول (تعریف UI) به صورت کامنت مخفی کردیم. بنابراین ویرایش State برنامه اولویت بعدی ما خواهد بود و از آنجایی که کار پیچیده ای می باشد در دو جلسه مجزا انجام خواهد شد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.