برنامه مدیریت کالری غذا: محاسبه total calories

Tracalorie Project: Calculating Total Calories

21 مرداد 1399
برنامه ی مدیریت کالری غذا: محاسبه ی total calories

تا این قسمت از کار می توانیم آیتم های غذایی را از کاربر دریافت کرده و در 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 برنامه اولویت بعدی ما خواهد بود و از آنجایی که کار پیچیده ای می باشد در دو جلسه مجزا انجام خواهد شد.

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

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