برنامه مدیریت کالری غذا: دریافت و نمایش آیتم‌ها

Tracalorie Project: Receive and Display Items

21 مرداد 1399
برنامه ی مدیریت کالری غذا: دریافت و نمایش آیتم ها

در قسمت قبل آیتم های غذایی را در data structure یا همان state برنامه را تعریف و خلاصه ای از برخی از کنترلرها را نیز پیاده سازی کردیم. اگر یادتان نباشد برای خالی نبودن این آیتم ها از چند آیتم فرضی و از پیش تعیین شده به شکل زیر استفاده کرده بودیم:

  // Data Structure / State
  const data = {
    items: [
      {id: 0, name: 'Steak Dinner', calories: 1200},
      {id: 1, name: 'Cookie', calories: 400},
      {id: 2, name: 'Eggs', calories: 300}
    ],
    currentItem: null,
    totalCalories: 0
  }

اما هنوز هیچ کدام از این آیتم ها را به کاربر نمایش نمی دهیم. هدف این جلسه نمایش این آیتم ها در لیست HTML است، گرچه که بعدا باید کاری کنیم که از طریق local storage ذخیره و دریافت شوند. برای شروع متدی به نام getItems را در قسمت عمومی ItemCtrl تعریف می کنیم:

  // Public methods
  return {
    getItems: function(){
      return data.items;
    },
    logData: function(){
      return data;
    }
  }
})();

این متد آیتم های غذایی را به ما می دهد. از طرفی ما می خواهیم زمانی که برنامه برای اولین بار اجرا شد، حتما تمام آیتم های موجود نیز در آن بارگذاری شده و به کاربر نمایش داده شوند. به همین خاطر باید منطق این کد ها را در init (درون کنترلر اصلی App) بنویسیم چرا که مسئول راه اندازی اولیه برنامه ما است اما از طرفی هر تغییری در UI برنامه باید از طریق کنترلر آن انجام شود. با این حساب ابتدا درون تابع init در کنترلر App می گوییم:

      const items = ItemCtrl.getItems();

سپس آن را log می کنیم تا مطمئن شویم به درستی کار می کند:

// App Controller
const App = (function(ItemCtrl, UICtrl){

  // Public methods
  return {
    init: function(){
      // Fetch items from data structure
      const items = ItemCtrl.getItems();

      console.log(items);
    }
  }
  
})(ItemCtrl, UICtrl);

با اجرای این کد باید در قسمت کنسول مرورگر شاهد نمایش هر سه آیتم غذایی تعریف شده در data structure باشید. اگر اینچنین شد می توانیم به مرحله بعد برویم. در مرحله بعد متدی را صدا می زنیم که بعدا درون کنترلر UI تعریف می کنیم:

// App Controller
const App = (function(ItemCtrl, UICtrl){

  // Public methods
  return {
    init: function(){
      // Fetch items from data structure
      const items = ItemCtrl.getItems();

      // Populate list with items
      UICtrl.populateItemList(items);
    }
  }
  
})(ItemCtrl, UICtrl);

من نام این متد را populateItemList گذاشته ام اما واقعا به سلیقه خودتان بستگی دارد که چه نامی برایش انتخاب کنید. در تابع بالا (init) که به محض باز شدن برنامه اجرا می شود، آیتم های غذایی دریافت شده و سپس توسط متد فرضی ما (populateItemList) درون UI نمایش داده می شوند.حتما شما هم می دانید که مرحله بعد تعریف کردن این متد است:

// UI Controller
const UICtrl = (function(){
  const UISelectors = {
    itemList: '#item-list'
  }
  
  // Public methods
  return {
    populateItemList: function(items){

    }
  }
})();

این بدنه متد ما است. یادتان باشد که احتمال دارد آیتم های ما بیشتر از یک عدد باشند بنابراین باید با استفاده از یک حلقه جاوا اسکریپتی بین آیتم ها گردش کنیم و هر کدام را درون یک <li> قرار بدهیم. در نهایت تمام این موارد را یکجا وارد index.html می کنیم (تگ <ul> را از قبل درون index.html تعریف کرده بودیم). بنابراین می گوییم:

// UI Controller
const UICtrl = (function(){
  const UISelectors = {
    itemList: '#item-list'
  }
  
  // Public methods
  return {
    populateItemList: function(items){
      let html = '';

      items.forEach(function(item){
        html += `<li class="collection-item" id="item-${item.id}">
        <strong>${item.name}: </strong> <em>${item.calories} Calories</em>
        <a href="#" class="secondary-content">
          <i class="edit-item fa fa-pencil"></i>
        </a>
      </li>`;
      });

      // Insert list items
      document.querySelector(UISelectors.itemList).innerHTML = html;
    }
  }
})();

من در تابع بالا از حلقه forEach استفاده کرده ام تا با هر کدام از آیتم های غذایی یک <li> ایجاد کنم. همانطور که می بینید هر <li> یک id دارد که برای مقدارش از همان id آیتم غذایی استفاده کرده ایم. سپس یک کلاس به نام collection-item داریم که مربوط به کتابخانه materialize است. نام آیتم را نیز برابر با item.name گرفته ایم و بقیه کد ها نیز واضح است. من کد این <li> را دقیقا از قسمت کامنت شده درون فایل index.html (جلسه اول) کپی کرده ام. پس از ایجاد این <li>، آن ها را با استفاده از querySelector وارد فایل index.html کرده ایم.

توجه داشته باشید که در قسمت ابتدایی این کنترلر یک شیء به نام UISelectors را داریم که برای راحتی کار تعریف کرده ام (اگر یادتان باشد #item-list در واقع آیدی <ul> ما در index.html بود). با انجام این کار id قسمت های مورد نظر از HTML را یکجا ذخیره کرده و نیازی به چک کردن فایل index.html نداریم. مثلا اگر در قسمتی از برنامه چیزی تغییر کند، دیگر نیازی به تغییر آن در سرتاسر کد نیست بلکه به راحتی از یک قسمت واحد ویرایش خواهد شد. با ذخیره این کد و رفتن به مرورگر متوجه می شویم که آیتم ها اضافه شده اند:

اضافه شدن آیتم های غذایی به UI
اضافه شدن آیتم های غذایی به UI

حالا می توانیم مباحث را تا این قسمت جمع بندی کنیم. ما می خواهیم برنامه ای برای مدیریت تعداد کالری های مصرفی کاربران بسازیم و برای این کار از جاوا اسکریپت استفاده می کنیم. در مرحله اول گفتیم که می خواهیم از یکی از الگوهای برنامه نویسی جاوا اسکریپت به نام Reavealing Module Pattern استفاده کنیم، به همین دلیل است که مدیریت بخش های مختلف برنامه را به کنترلرهای مختلف واگذار کرده ایم. در ابتدای کار App اجرا شده و برنامه initialize (راه اندازی اولیه) می شود:

// App Controller
const App = (function(ItemCtrl, UICtrl){

  // Public methods
  return {
    init: function(){
      // Fetch items from data structure
      const items = ItemCtrl.getItems();

      // Populate list with items
      UICtrl.populateItemList(items);
    }
  }
  
})(ItemCtrl, UICtrl);

// Initialize App
App.init();

توجه کنید تا زمانی که App.init صدا زده نشود هیچ چیزی کار نخواهد کرد چرا که بارگذاری اصلی برنامه را به عهده App گذاشته ایم. با فراخوانی متد init ابتدا آیتم های غذایی از Data structure دریافت شده و سپس به تابعی به نام populateItemList ارسال می شوند. متد populateItemList نیز بین آیتم های غذایی گردش کرده و هر کدام را درون یک <li> خاص با یک ساختار خاص قرار می دهد. این ساختار ها همگی مربوط به HTML هستند و می توانید به سادگی آن ها را مشاهده کنید. برای ایجاد این ساختار از علامت های backtick استفاده کرده ایم (دکمه بالای Tab روی کیبورد شما) تا بتوانیم متغیر های item.name و ... را به صورت پویا درون رشته وارد کنیم. در نهایت این رشته وارد فایل HTML ما شده و درون <ul> قرار می گیرد تا نمایش داده شود.

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

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