MATIN MOLKARA
SERIES: JavaScript — PART 90 OF 108

90- آموزش جاوااسکریپت | پروژه عملی: قسمت 3 از 12- شروع ساختار ماژول‌های پروژه Calorie Tracker

در این بخش، ساختار اولیه ماژول‌های پروژه Calorie Tracker را با Module Pattern پیاده‌سازی می‌کنیم. همچنین فایل app.js را به پروژه متصل کرده، Item Controller را می‌سازیم و تابع init را برای راه‌اندازی اولیه برنامه آماده می‌کنیم.

در بخش قبل، رابط کاربری پروژه را با استفاده از Materialize CSS آماده کردیم.
در این بخش، وارد مرحله پیاده‌سازی ساختار JavaScript می‌شویم و پایه ماژول‌های اصلی برنامه را می‌سازیم.

در ابتدای کار، باید فایل app.js را به فایل HTML متصل کنیم تا کدهای برنامه اجرا شوند. سپس با استفاده از Module Pattern، ساختار کلی پروژه را به چند کنترلر مستقل تقسیم می‌کنیم.


اتصال فایل app.js به HTML

ابتدا باید مطمئن شویم فایل JavaScript اصلی پروژه به صفحه متصل شده است. این فایل باید در انتهای body و بعد از اسکریپت‌های jQuery و Materialize قرار بگیرد.

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="app.js"></script>

قرار دادن فایل app.js در این بخش باعث می‌شود که ابتدا وابستگی‌های موردنیاز بارگذاری شوند و سپس کد اصلی برنامه اجرا شود.


ساختار کلی ماژول‌ها

در این پروژه، کدها را به چند بخش اصلی تقسیم می‌کنیم تا مدیریت برنامه ساده‌تر و منظم‌تر باشد. این ماژول‌ها عبارت‌اند از:

  • Storage Controller برای کار با Local Storage
  • Item Controller برای مدیریت داده‌های مربوط به آیتم‌ها
  • UI Controller برای کنترل رابط کاربری
  • App Controller برای هماهنگ‌سازی کل برنامه

در این بخش، ماژول Storage Controller را فقط در نظر می‌گیریم و پیاده‌سازی آن را به مراحل بعدی موکول می‌کنیم.


تعریف محل کنترلرها در فایل app.js

برای شروع، می‌توانیم با چند کامنت ساختار کلی فایل را مشخص کنیم:

// Storage Controller

// Item Controller

// UI Controller

// App Controller

این کار باعث می‌شود از همان ابتدا معماری برنامه روشن باشد و هر بخش در جای مناسب خود توسعه پیدا کند.


شروع با Item Controller

اولین ماژولی که پیاده‌سازی می‌کنیم، Item Controller است.
این ماژول مسئول مدیریت داده‌های مربوط به وعده‌های غذایی و کالری‌ها خواهد بود.

برای ساخت این ماژول از IIFE یا همان Immediately Invoked Function Expression استفاده می‌کنیم.

const ItemCtrl = (function () {

})();

IIFE چیست؟

IIFE یک تابع است که بلافاصله پس از تعریف، اجرا می‌شود.
این الگو به ما کمک می‌کند:

  • متغیرها و داده‌های داخلی را خصوصی نگه داریم
  • فقط متدهای موردنیاز را در اختیار بخش‌های دیگر قرار دهیم
  • از شلوغ‌شدن فضای سراسری برنامه جلوگیری کنیم

تعریف UI Controller

به‌همین شکل، کنترلر رابط کاربری را نیز تعریف می‌کنیم:

const UICtrl = (function () {

})();

این بخش در ادامه مسئول کارهایی مانند:

  • دریافت مقادیر فرم
  • نمایش یا مخفی‌کردن دکمه‌ها
  • رندر کردن آیتم‌ها در لیست
  • به‌روزرسانی مجموع کالری‌ها

خواهد بود.


تعریف App Controller

در مرحله بعد، یک کنترلر اصلی برای هماهنگ‌کردن بخش‌های مختلف برنامه می‌سازیم. این ماژول، کنترلرهای دیگر را دریافت می‌کند و نقطه اتصال بخش‌های مختلف برنامه خواهد بود.

const App = (function (ItemCtrl, UICtrl) {

})(ItemCtrl, UICtrl);

در ادامه، زمانی که Storage Controller را نیز پیاده‌سازی کنیم، آن را هم به این ماژول اضافه خواهیم کرد.


ساخت سازنده Item

برای اینکه بتوانیم آیتم‌های جدید بسازیم، به یک سازنده نیاز داریم. هر آیتم شامل سه ویژگی اصلی است:

  • id
  • name
  • calories

کد سازنده به این صورت خواهد بود:

const ItemCtrl = (function () {
  const Item = function (id, name, calories) {
    this.id = id;
    this.name = name;
    this.calories = calories;
  };
})();

این سازنده هر بار که یک آیتم جدید ایجاد شود، شیئی با این سه ویژگی تولید می‌کند.


تعریف ساختار داده برنامه

بعد از سازنده، باید یک ساختار داده برای نگهداری اطلاعات برنامه داشته باشیم. این ساختار، نقش state داخلی برنامه را ایفا می‌کند.

const ItemCtrl = (function () {
  const Item = function (id, name, calories) {
    this.id = id;
    this.name = name;
    this.calories = calories;
  };

  const data = {
    items: [],
    currentItem: null,
    totalCalories: 0
  };
})();

اجزای data

این آبجکت شامل سه بخش اصلی است:

1. items

آرایه‌ای از همه آیتم‌های ثبت‌شده در برنامه

2. currentItem

آیتمی که در حال حاضر برای ویرایش انتخاب شده است

3. totalCalories

مجموع کالری همه آیتم‌ها


تعریف داده‌های اولیه

برای شروع و آزمایش منطق برنامه، می‌توانیم چند آیتم نمونه را به‌صورت موقت در data.items قرار دهیم:

const ItemCtrl = (function () {
  const Item = function (id, name, calories) {
    this.id = id;
    this.name = name;
    this.calories = calories;
  };

  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
  };
})();

این داده‌ها فقط برای شروع کار و تست ساختار استفاده می‌شوند و در ادامه به‌صورت پویا از طریق فرم به برنامه اضافه خواهند شد.


مفهوم private و public در Module Pattern

یکی از مهم‌ترین ویژگی‌های Module Pattern این است که متغیرها و توابعی که داخل ماژول تعریف می‌شوند، به‌صورت پیش‌فرض خصوصی هستند.

برای مثال، اگر data را داخل ItemCtrl تعریف کنیم، از بیرون ماژول به آن دسترسی مستقیم نخواهیم داشت.
برای در دسترس قرار دادن بخشی از قابلیت‌های ماژول، باید آن‌ها را در return برگردانیم.


ساخت متد logData

برای آزمایش و مشاهده داده‌های داخلی، یک متد عمومی به نام logData می‌سازیم که data را برگرداند.

const ItemCtrl = (function () {
  const Item = function (id, name, calories) {
    this.id = id;
    this.name = name;
    this.calories = calories;
  };

  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
  };

  return {
    logData: function () {
      return data;
    }
  };
})();

اکنون این متد از بیرون ماژول قابل‌دسترسی است.


تست ItemCtrl

برای بررسی عملکرد ماژول، می‌توانیم در کنسول یا در بخشی از برنامه، متد logData را فراخوانی کنیم:

console.log(ItemCtrl.logData());

خروجی این دستور، ساختار کامل داده‌های داخلی ماژول را نمایش می‌دهد.


بازگرداندن متد init در App Controller

ماژول App قرار است فقط یک متد اصلی به نام init را در اختیار قرار دهد.
این متد برای راه‌اندازی اولیه برنامه استفاده می‌شود.

const App = (function (ItemCtrl, UICtrl) {
  return {
    init: function () {
      console.log('Initializing App...');
    }
  };
})(ItemCtrl, UICtrl);

اجرای init

پس از تعریف App، می‌توانیم متد init را فراخوانی کنیم تا مطمئن شویم ساختار برنامه به‌درستی اجرا می‌شود.

App.init();

اگر همه چیز درست باشد، هنگام بارگذاری صفحه، پیام زیر در کنسول نمایش داده می‌شود:

Initializing App...

نقش init در برنامه

تابع init محل اجرای عملیات اولیه برنامه است. در ادامه، کارهایی مانند موارد زیر را در این تابع قرار می‌دهیم:

  • دریافت آیتم‌ها از Item Controller
  • نمایش آیتم‌ها در رابط کاربری
  • ریست‌کردن حالت ویرایش
  • ثبت event listenerهای اولیه
  • آماده‌سازی وضعیت شروع برنامه

در واقع، هر چیزی که باید هنگام بارگذاری اولیه برنامه اجرا شود، در این متد قرار می‌گیرد.


نسخه کامل کد این بخش

در پایان این مرحله، کد app.js به‌شکل زیر خواهد بود:

// Storage Controller

// Item Controller
const ItemCtrl = (function () {
  const Item = function (id, name, calories) {
    this.id = id;
    this.name = name;
    this.calories = calories;
  };

  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
  };

  return {
    logData: function () {
      return data;
    }
  };
})();

// UI Controller
const UICtrl = (function () {
  return {};
})();

// App Controller
const App = (function (ItemCtrl, UICtrl) {
  return {
    init: function () {
      console.log('Initializing App...');
      console.log(ItemCtrl.logData());
    }
  };
})(ItemCtrl, UICtrl);

App.init();

جمع‌بندی

در این بخش، ساختار اولیه JavaScript پروژه Calorie Tracker را با استفاده از Module Pattern ایجاد کردیم. در این مرحله:

  • فایل app.js را به HTML متصل کردیم
  • ساختار کلی کنترلرها را مشخص کردیم
  • ماژول Item Controller را ایجاد کردیم
  • سازنده Item را نوشتیم
  • ساختار data را به‌عنوان state داخلی برنامه تعریف کردیم
  • متد logData را برای تست داده‌ها ساختیم
  • ماژول App و متد init را پیاده‌سازی کردیم

در بخش بعدی، متد دریافت آیتم‌ها را در Item Controller ایجاد می‌کنیم و سپس داده‌ها را با کمک UI Controller در رابط کاربری نمایش خواهیم داد.

// 0 comments
#JavaScript#Module Pattern#IIFE#App Controller#UI Controller#Item Controller#Calorie Tracker#JavaScript Project#آموزش جاوااسکریپت#پروژه جاوااسکریپت

نظرات (0)

نظر خود را بنویسید