۰ دیدگاه نظر سحر پاشائی
MEAN Stack چیست؟ (آموزش ساخت اپلیکیشن مدیریت کارمندان با MEAN Stack)
سرفصل‌های مقاله
  • MEAN Stack چیست؟
  • کاربردهای MEAN Stack
  • مزایای استفاده از MEAN Stack
  • معایب  MEAN Stack
  • چه زمانی می‌تونی از MEAN Stack استفاده کنی؟
  • استفاده از MEAN Stack با MongoDB Atlas
  • امنیت MEAN Stack چطوره؟
  • تفاوت MEAN Stack Developer و Full Stack Developer
  • نقش‌ها و مسئولیت‌های MEAN Stack Developer
  • مهارت‌های MEAN Stack Developer
  • شروع کار با MEAN Stack
  • مثال کاربردی: ساخت یک اپلیکیشن مدیریت کارمندان با MEAN Stack
  • سوالات متداول
  • جمع‌بندی

همیشه برای توسعه‌دهنده‌ها مهم بوده که بتونن اپلیکیشن‌هاشون رو روی یه مجموعه یکپارچه از تکنولوژی‌های پایه بسازن. وقتی از همون اول کار یه سری ابزار استاندارد و هماهنگ در اختیار داشته باشی، می‌تونی بیشتر وقتت رو روی ساختن چیزی بذاری که کسب‌وکارت رو متمایز می‌کنه. اینجوری دیگه لازم نیست از صفر شروع کنی و کلی قطعه پراکنده رو به هم بچسبونی. اینجاست که MEAN Stack وارد می‌شه و همه این کارها رو برات راحت می‌کنه. آماده‌ای بریم سراغ این تکنولوژی جذاب؟!

MEAN Stack چیست؟

MEAN Stack یه ترکیب از چهار تکنولوژی قدرتمنده که بهت اجازه می‌ده یه اپلیکیشن وب فول استک بسازی. این چهار تکنولوژی عبارتند از:

  • MongoDB: یه پایگاه داده NoSQL که داده‌ها رو به صورت سند ذخیره می‌کنه.
  • Express.js: یه فریم‌ورک سبک برای توسعه سرور با استفاده از Node.js.
  • Angular: یه فریم‌ورک فرانت‌اند قدرتمند که توسط گوگل توسعه داده شده.
  • Node.js: یه محیط اجرایی برای جاوا اسکریپت که روی سرور استفاده می‌شه.

با استفاده از این چهار ابزار، می‌تونی یه اپلیکیشن وب کامل بسازی که از پایگاه داده تا واسط کاربری همه چی رو پوشش بده. حالا بیا هر کدوم از این ابزارها رو به طور جداگانه بررسی کنیم.

MongoDB

MongoDB یه پایگاه داده NoSQL هست که بهت اجازه می‌ده داده‌ها رو به صورت سندهای JSON ذخیره کنی. این یعنی می‌تونی داده‌ها رو به صورت ساختار یافته و با انعطاف بالا ذخیره کنی. برای مثال، فرض کن می‌خوای اطلاعات کاربران رو ذخیره کنی. با MongoDB می‌تونی به راحتی سندی به شکل زیر بسازی:

{
  "name": "John Doe",
  "email": "john@example.com",
  "age": 30
}

این انعطاف‌پذیری باعث می‌شه که بتونی به راحتی ساختار داده‌هات رو تغییر بدی و با نیازهای پروژه‌ت تطبیق بدی.

Express.js

Express.js یه فریم‌ورک سبک و قدرتمنده که برای ساخت سرور با استفاده از Node.js استفاده می‌شه. این فریم‌ورک بهت اجازه می‌ده تا با استفاده از متدهای ساده، روت‌های مختلف بسازی و درخواست‌های HTTP رو مدیریت کنی. مثلا، با استفاده از Express.js می‌تونی یه سرور ساده به شکل زیر بسازی:

const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res.send('Hello, World!');
});
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

Angular

Angular یه فریم‌ورک فرانت‌اند قدرتمنده که توسط گوگل توسعه داده شده. این فریم‌ورک بهت اجازه می‌ده تا اپلیکیشن‌های تک‌صفحه‌ای (SPA) بسازی که تجربه کاربری فوق‌العاده‌ای دارن. با Angular می‌تونی به راحتی کامپوننت‌های مختلف بسازی و داده‌ها رو بین اون‌ها به اشتراک بذاری. برای مثال، می‌تونی یه کامپوننت ساده به شکل زیر بسازی:

import { Component } from '@angular/core';
@Component({
  selector: 'app-hello',
  template: `<h1>Hello, {{ name }}!</h1>`,
})
export class HelloComponent {
  name = '7Learn';
}

Node.js

Node.js یه محیط اجرایی برای جاوا اسکریپته که روی سرور استفاده می‌شه. این محیط بهت اجازه می‌ده تا با استفاده از جاوا اسکریپت، کدهای سمت سرور بنویسی و از همون زبان برای فرانت‌اند و بک‌اند استفاده کنی. این یعنی نیاز نیست برای هر بخش از اپلیکیشن‌ت زبان‌های مختلف یاد بگیری و می‌تونی همه چی رو با جاوا اسکریپت انجام بدی.

کاربردهای MEAN Stack

حالا که با MEAN Stack آشنا شدی، بیا ببینیم کجاها می‌تونی از این تکنولوژی خفن استفاده کنی. MEAN Stack برای همه نوع اپلیکیشن مناسب نیست، اما جاهایی که به درد می‌خوره، حسابی می‌درخشه. از اونجایی که MEAN Stack قابلیت مقیاس‌پذیری بالایی داره و می‌تونه تعداد زیادی کاربر رو همزمان مدیریت کنه، یه انتخاب عالی برای توسعه اپلیکیشن‌های ابری (Cloud-native) هست. همچنین، فریم‌ورک Angular که در بخش فرانت‌اند استفاده می‌شه، ایده‌آل برای ساخت اپلیکیشن‌های تک‌صفحه‌ای (SPA) است که همه اطلاعات و امکانات رو روی یک صفحه ارائه می‌ده. بیا چند تا مثال از کاربردهای MEAN Stack ببینیم:

تقویم‌ها

اگر دنبال ساخت یه تقویم آنلاین هستی که کاربران بتونن رویدادها و برنامه‌هاشون رو مدیریت کنن، MEAN Stack می‌تونه انتخاب خوبی باشه. با استفاده از MongoDB می‌تونی داده‌ها رو به صورت ساختار یافته ذخیره کنی و با Angular یه واسط کاربری زیبا و کاربرپسند بسازی.

ردیابی هزینه‌ها

یه اپلیکیشن ردیابی هزینه‌ها که کاربران بتونن مخارج روزانه‌شون رو ثبت و مدیریت کنن، نیاز به یه پایگاه داده قوی و یه واسط کاربری منعطف داره. MEAN Stack با ترکیب MongoDB و Angular بهت اجازه می‌ده تا یه اپلیکیشن کارآمد و مقیاس‌پذیر برای مدیریت هزینه‌ها بسازی.

سایت‌های تجمیع اخبار

برای ساختن سایت‌های تجمیع اخبار که اطلاعات رو از منابع مختلف جمع‌آوری می‌کنن و به کاربران نمایش می‌دن، MEAN Stack یه گزینه عالیه. با استفاده از Node.js و Express.js می‌تونی اطلاعات رو از منابع مختلف جمع‌آوری و پردازش کنی و با Angular اون‌ها رو به کاربران نمایش بدی.

نقشه‌برداری و مکان‌یابی

اپلیکیشن‌های نقشه‌برداری و مکان‌یابی نیاز به پردازش سریع داده‌ها و نمایش دقیق اطلاعات دارن. MEAN Stack با قابلیت مقیاس‌پذیری بالا و انعطاف‌پذیری زیاد می‌تونه بهت کمک کنه تا یه اپلیکیشن نقشه‌برداری و مکان‌یابی کارآمد و قابل اعتماد بسازی.

اپلیکیشن‌های چت و پیام‌رسانی

اگر به فکر ساختن یه اپلیکیشن چت یا پیام‌رسانی هستی که کاربران بتونن به صورت همزمان با هم ارتباط برقرار کنن، MEAN Stack یه انتخاب عالیه. با استفاده از Socket.io و Node.js می‌تونی ارتباطات بی‌درنگ (real-time) رو مدیریت کنی و با Angular یه واسط کاربری جذاب و کاربرپسند بسازی.

همون‌طور که دیدی، MEAN Stack می‌تونه توی زمینه‌های مختلفی به کارت بیاد و بهت کمک کنه تا اپلیکیشن‌های متنوع و قدرتمندی بسازی. فقط کافیه با خلاقیت و دانش خودت از این ابزارها استفاده کنی و بهترین نتیجه رو بگیری.

مزایای استفاده از MEAN Stack

حالا که با هر کدوم از ابزارهای MEAN Stack آشنا شدیم، بیا ببینیم چرا استفاده از این تکنولوژی می‌تونه یه انتخاب عالی برای توسعه وب باشه.

یکپارچگی و هماهنگی

یکی از بزرگترین مزایای MEAN Stack اینه که تمام ابزارهای مورد استفاده در این تکنولوژی با همدیگه هماهنگ و یکپارچه هستن. این یعنی می‌تونی با استفاده از یه زبان (جاوا اسکریپت) تمام بخش‌های اپلیکیشن‌ت رو بنویسی و نیازی به یادگیری زبان‌های مختلف نداری.

انعطاف‌پذیری بالا

MEAN Stack بهت انعطاف‌پذیری بالایی می‌ده تا به راحتی ساختار داده‌ها و اپلیکیشن‌ت رو تغییر بدی. با MongoDB می‌تونی به راحتی داده‌ها رو به شکل سند ذخیره کنی و با Angular می‌تونی به راحتی رابط کاربری‌ت رو تغییر بدی.

عملکرد بالا

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

پشتیبانی از جامعه بزرگ

هر کدوم از ابزارهای MEAN Stack توسط جامعه بزرگی از توسعه‌دهنده‌ها پشتیبانی می‌شن. این یعنی همیشه می‌تونی به منابع آموزشی و پشتیبانی فنی دسترسی داشته باشی و مشکلاتت رو به راحتی حل کنی.

معایب  MEAN Stack

تا اینجا درباره مزایا و کاربردهای MEAN Stack حرف زدیم. اما هیچ تکنولوژی‌ای بدون عیب و ایراد نیست. حالا بیا یه نگاه دقیق‌تر به معایب و چالش‌های MEAN Stack بندازیم.

یادگیری زمان‌بر

یکی از بزرگترین چالش‌های MEAN Stack اینه که اگر تازه‌کاری، یادگیری همه ابزارهای این استک ممکنه برات زمان‌بر باشه. هر چند که همه چیز با جاوا اسکریپت کار می‌کنه، ولی یادگیری عمیق MongoDB، Express.js، Angular و Node.js هر کدوم خودش یه چالش جداست. باید حسابی وقت بذاری و با هر کدوم از این تکنولوژی‌ها خوب آشنا بشی تا بتونی بهترین استفاده رو ازشون بکنی.

پیکربندی پیچیده

تنظیم و پیکربندی اولیه MEAN Stack ممکنه برات پیچیده باشه، به‌خصوص اگر تجربه کافی نداشته باشی. هر کدوم از این ابزارها نیاز به تنظیمات خاص خودش داره و اگه یکی از اون‌ها رو اشتباه تنظیم کنی، ممکنه کل پروژه‌ت به مشکل بخوره. پس باید حسابی حواست به جزئیات باشه و از منابع و داکیومنت‌های موجود استفاده کنی.

مقیاس‌پذیری

درسته که MEAN Stack بهت کمک می‌کنه اپلیکیشن‌های مقیاس‌پذیر بسازی، ولی این مقیاس‌پذیری هم خودش چالش‌های خاصی داره. مدیریت تعداد زیاد کاربر و درخواست‌های همزمان می‌تونه منابع سرورت رو حسابی تحت فشار بذاره. باید حواست به بهینه‌سازی کدها و استفاده از بهترین روش‌ها برای مدیریت منابع باشه تا اپلیکیشن‌ت همیشه روان و سریع کار کنه.

مشکل با SEO

اگر داری یه اپلیکیشن تک‌صفحه‌ای (SPA) می‌سازی، باید بدونی که این نوع اپلیکیشن‌ها به خاطر لود شدن تمام محتوا با جاوا اسکریپت، ممکنه با مشکلاتی در زمینه SEO مواجه بشن. موتورهای جستجو ممکنه نتونن به خوبی محتوای صفحات رو بخونن و این می‌تونه روی رتبه‌بندی سایتت توی نتایج جستجو تاثیر منفی بذاره. برای حل این مشکل می‌تونی از تکنیک‌های مختلفی مثل سرور ساید رندرینگ (SSR) استفاده کنی.

وابستگی به جامعه متن‌باز

هر چند که MEAN Stack توسط جامعه بزرگی از توسعه‌دهنده‌ها پشتیبانی می‌شه، ولی وابستگی به ابزارهای متن‌باز همیشه ریسک‌هایی داره. ممکنه بعضی از کتابخانه‌ها و ابزارهای مورد استفاده به‌روزرسانی نشن یا مشکلات امنیتی داشته باشن که باید حواست به این موضوعات هم باشه.

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

MEAN در مقابل MERN و MEVN

حالا که با MEAN Stack آشنا شدی، باید بدونی که تنها گزینه موجود نیست. دوتا استک دیگه هم هستن که حسابی محبوبن: MERN و MEVN. بیا ببینیم اینا چه فرقی با MEAN دارن.

MERN Stack

MERN Stack هم مثل MEAN عمل می‌کنه، با این تفاوت که به جای Angular، از ReactJS استفاده می‌کنه. ReactJS توسط فیسبوک توسعه داده شده و برای ساخت رابط‌های کاربری سریع و تعاملی خیلی خوبه. این استک بیشتر برای اپلیکیشن‌های بزرگ و پیچیده که نیاز به رابط کاربری سریع دارن، مناسبه.

MEVN Stack

MEVN Stack هم یه جایگزین دیگه‌ست که به جای Angular از Vue.js استفاده می‌کنه. Vue.js یه فریم‌ورک جاوا اسکریپت ساده و پیشرفته‌ست که به خاطر سادگی و سرعت یادگیریش معروفه. MEVN بیشتر برای پروژه‌های کوچک تا متوسط که توسعه سریع و ساده مد نظره، به کار میاد.

تفاوت‌های اصلی MEAN، MERN و MEVN

تفاوت اصلی بین این سه استک توی انتخاب فریم‌ورک فرانت‌اند هست، در حالی که همه‌شون از MongoDB، Express.js و Node.js برای بک‌اند استفاده می‌کنن. بیا چند تا فاکتور مهم رو بررسی کنیم:

  • آشنایی توسعه‌دهنده: یکی از مهمترین فاکتورها توی انتخاب استک، آشنایی و راحتی تیم توسعه‌دهنده با اون فریم‌ورکه. هر تیمی معمولاً بر اساس تجربه و راحتی اعضاش یه استک رو انتخاب می‌کنه.
  • اپلیکیشن‌های تک‌صفحه‌ای پیچیده (SPA): اگه دنبال ساخت یه SPA پیچیده و پر از امکانات هستی، MEAN Stack با Angular می‌تونه انتخاب خوبی باشه، چون Angular توسط گوگل پشتیبانی می‌شه و برای اپلیکیشن‌های وب پیچیده خیلی مناسبه.
  • اپلیکیشن‌های بزرگ با رابط کاربری سریع: ReactJS توی MERN Stack به خاطر سرعت بالا و تعاملی بودنش خیلی معروفه. برای اپلیکیشن‌های بزرگ که نیاز به رابط کاربری سریع دارن، MERN می‌تونه گزینه بهتری باشه.
  • سادگی: Vue.js توی MEVN Stack به خاطر سادگی و راحتی استفاده معروفه. اگه دنبال توسعه سریع و ساده برای پروژه‌های کوچک تا متوسط هستی، MEVN یه انتخاب عالیه.

چه زمانی می‌تونی از MEAN Stack استفاده کنی؟

حالا که با MEAN Stack آشنا شدی، بریم ببینیم کجاها می‌تونی از این استک جذاب استفاده کنی. MEAN از سه لایه اصلی تشکیل شده: لایه نمایش (Angular.js)، لایه برنامه (Express.js و Node.js) و لایه پایگاه داده (MongoDB). این یعنی از نمایش داده‌ها تا مدیریت درخواست‌ها و ذخیره‌سازی اطلاعات، همه چی توی یه پکیج آماده هست.

چرا MEAN Stack؟

اگه داری یه اپلیکیشن جاوا اسکریپتی می‌سازی، به‌ویژه با نود جی‌اس، MEAN یه گزینه عالی برات محسوب می‌شه. MongoDB داده‌ها رو به صورت JSON ذخیره می‌کنه و کار باهاش خیلی راحته. کوئری‌ها و رابط خط فرمان (CLI) هم با جاوا اسکریپت کار می‌کنن، پس همه چیز یکپارچه و سازگار می‌شه.

MongoDB پر از ویژگی‌های پیشرفته مثل ایندکس‌گذاری و جستجوی عمیق در اسناد JSON هست. درایورهای قدرتمند Node.js بومی داره و برای مقیاس‌پذیری افقی طراحی شده. استفاده از MongoDB Atlas، که یه سرویس ابری مدیریت شده‌ست، این کار رو حتی راحت‌تر هم می‌کنه.

کجاها می‌تونی از MEAN Stack استفاده کنی؟

  • API با ترافیک بالا: اگه نیاز به ساخت API داری که درخواست‌های زیادی رو پردازش کنه، MEAN خیلی به کارت میاد.
  • اپلیکیشن وب ساده: برای ساخت یه وبسایت ساده که اطلاعات رو از کاربر بگیره و ذخیره کنه، MEAN انتخاب خوبیه.
  • میکروسرویس‌ها: اگه می‌خوای سرویس‌های کوچیک و مستقلی بسازی که هر کدوم کار خاصی رو انجام بدن، MEAN می‌تونه انتخاب عالی باشه.

استفاده از MEAN Stack با MongoDB Atlas

درایور Node.js برای MongoDB کار با MongoDB رو در داخل یه اسکریپت Node.js ساده و شهودی می‌کنه، و این باعث می‌شه وقت کمتری صرف کنی و بهره‌وری‌ت بالا بره.

اول از همه، نیاز به یه پایگاه داده MongoDB داری. ساده‌ترین راه برای شروع کار با MongoDB اینه که یه کلاستر رایگان توی MongoDB Atlas بسازی، که یه دیتابیس مستند ابری چندگانه و مدیریت شده‌ست.

دیتابیس‌های Atlas به راحتی مستقر و مقیاس‌پذیر هستن و یه URI سازگار برای اتصال فراهم می‌کنن. برای اطلاعات بیشتر می‌تونی به مستندات رسمی MongoDB برای اتصال به یه کلاستر مراجعه کنی.

اتصالات Atlas با نام کاربری/رمز عبور داخلی و رمزگذاری TLS از ابتدا همراه هستن. همچنین، این اتصالات بهت اجازه می‌دن از ویژگی‌های پیشرفته امنیتی MongoDB مثل احراز هویت با گواهینامه/IAM، ال‌دی‌ای‌پی (LDAP)، رمزگذاری در حالت استراحت، و حسابرسی با یک کلیک استفاده کنی.

علاوه بر این، یه پروژه Atlas می‌تونه از پلتفرم برنامه‌های Atlas App Services برای یکپارچه‌سازی راحت با ارائه‌دهندگان احراز هویت مختلف مثل گوگل، فیسبوک، JWT و احراز هویت سفارشی استفاده کنه.

مدیریت و مقیاس‌پذیری Atlas خیلی راحته و بزرگترین مزیتش اینه که لایه داده ارزشمندترین بخش MEAN Stack رو پشتیبانی و ایمن می‌کنه.

امنیت MEAN Stack چطوره؟

ما پیشنهاد می‌کنیم از MEAN Stack با MongoDB Atlas استفاده کنی، چون Atlas دارای اعتبارنامه‌های داخلی، فایروال و رمزگذاری End-to-End هست که بهترین پایه برای ایمن کردن MongoDBته.

علاوه بر این، MEAN Stack دارای یک جداسازی سه‌لایه قوی هست که اگه با بهترین روش‌ها و شبکه‌سازی صحیح استفاده بشه، باید از دسترسی کاربران نهایی به منطق کسب‌وکار و حتی لایه پایگاه داده‌ت جلوگیری کنه. بنابراین، اپلیکیشن‌ت به صورت پیش‌فرض طراحی شده تا از تعاملات مخرب کاربران که ممکنه اپلیکیشن‌ت رو به خطر بندازه (مثل تزریق کوئری، دستکاری کد، تقلید پورت و غیره) جلوگیری کنه.

با خیال راحت از MEAN Stack استفاده کن و مطمئن باش که امنیت دیتابیس و اپلیکیشن‌ت تامین شده!

تفاوت MEAN Stack Developer و Full Stack Developer

در این بخش می‌خوایم درباره تفاوت بین یه MEAN Stack Developer و یه Full Stack Developer حرف بزنیم. ممکنه این اصطلاحات به نظرت پیچیده بیان، اما با یه توضیح ساده همه چی روشن می‌شه.

Full Stack Developer کیه؟

Full Stack Developer کسیه که توانایی کار کردن با هر دو بخش فرانت‌اند (frontend) و بک‌اند (backend) یه اپلیکیشن وب رو داره. این یعنی هم می‌تونه واسط کاربری جذاب بسازه و هم می‌تونه منطق سرور و پایگاه داده رو پیاده‌سازی کنه. یه Full Stack Developer معمولاً با تکنولوژی‌ها و فریم‌ورک‌های مختلفی مثل HTML، CSS، JavaScript، Python، Ruby، PHP، MySQL و غیره کار می‌کنه. این افراد توانایی طراحی، توسعه، تست و نگهداری کل اپلیکیشن رو دارن و به خاطر داشتن دانش گسترده در این زمینه‌ها، برای شرکت‌ها بسیار ارزشمند هستن.

MEAN Stack Developer کیه؟

MEAN Stack Developer هم مثل Full Stack Developer، توانایی کار با هر دو بخش فرانت‌اند و بک‌اند رو داره، اما با یه تفاوت مهم: این افراد فقط با تکنولوژی‌های MEAN Stack کار می‌کنن. این تکنولوژی‌ها شامل MongoDB، Express.js، Angular.js و Node.js هستن. MEAN Stack Developerها تخصصشون در جاوا اسکریپت و ابزارهای مربوط به اون هست و معمولاً برای پروژه‌هایی که به این تکنولوژی‌ها نیاز دارن، خیلی مناسبن.

معیار

Full Stack Developer

MEAN Stack Developer

تکنولوژی‌های مورد استفادهHTML، CSS، JavaScript، Python، Ruby، PHP، MySQL و غیرهMongoDB، Express.js، Angular.js، Node.js
دامنه دانشگسترده و شامل تکنولوژی‌ها و فریم‌ورک‌های مختلفمتمرکز بر جاوا اسکریپت و ابزارهای مربوط به آن
کاربردهاپروژه‌های بزرگ و پیچیده که نیاز به تکنولوژی‌های مختلف دارنپروژه‌های جاوا اسکریپتی و مقیاس‌پذیر
مزایاتوانایی تغییر بین فرانت‌اند و بک‌اند، مناسب برای پروژه‌های متنوعتوسعه سریع‌تر و ساده‌تر به خاطر یکپارچگی ابزارها
نمونه ابزارهاLAMP (Linux، Apache، MySQL، PHP)، MERN (MongoDB، Express، React، Node)تنها چهار تکنولوژی: MongoDB، Express.js، Angular.js، Node.js

مزایای Full Stack Developer:

  • توانایی کار با تکنولوژی‌های مختلف
  • قابلیت تغییر بین فرانت‌اند و بک‌اند بسته به نیاز پروژه
  • مناسب برای پروژه‌های بزرگ و پیچیده

مزایای MEAN Stack Developer:

  • تمرکز بر روی یک مجموعه تکنولوژی مشخص
  • توسعه سریع‌تر و ساده‌تر به خاطر یکپارچگی ابزارها
  • مناسب برای پروژه‌های جاوا اسکریپتی و مقیاس‌پذیر

هم Full Stack Developer و هم MEAN Stack Developer هر دو نقش مهمی در توسعه وب دارن، اما هر کدوم با توجه به تخصص‌ها و تکنولوژی‌های مورد استفاده‌شون برای پروژه‌های خاصی مناسب‌تر هستن. انتخاب بین این دو به نیازهای پروژه و تکنولوژی‌های مورد استفاده بستگی داره.

نقش‌ها و مسئولیت‌های MEAN Stack Developer

می‌خوای بدونی یه MEAN Stack Developer چه کارهایی انجام می‌ده؟ بیا این مسئولیت‌ها رو با هم بررسی کنیم:

  • جلسات با مشتریان یا مدیریت: باید با مشتریان یا مدیریت جلسه بذاری تا نیازهای پروژه رو جمع‌آوری کنی و بفهمی دقیقاً چه انتظاراتی از اپلیکیشن دارن.
  • ساخت کامپوننت‌های فرانت‌اند با AngularJS: مثلاً ساخت فرم‌ها، فیلترها و تنظیمات رابط کاربری.
  • ایجاد APIهای امن و نقاط پایانی با Node.js و Express: باید مطمئن بشی که APIهایی که می‌سازی امن هستن و به خوبی کار می‌کنن.
  • ادغام پایگاه داده MongoDB و بهینه‌سازی مدل‌های داده: باید داده‌ها رو به شکل مناسبی ذخیره کنی و مطمئن بشی که مدل‌های داده بهینه هستن.
  • توسعه منطق سرور برای اتصال فرانت‌اند به ذخیره‌سازی داده‌ها: باید منطق سرور رو طوری بنویسی که فرانت‌اند به راحتی به داده‌های بک‌اند دسترسی داشته باشه.
  • استفاده مجدد از کتابخانه‌های کد موجود و نوشتن کامپوننت‌های مدولار جدید: باید از کدهای موجود استفاده کنی و در صورت نیاز کامپوننت‌های جدید بنویسی.
  • تست در مرورگرها و دستگاه‌های مختلف: باید مطمئن بشی که اپلیکیشن روی همه مرورگرها و دستگاه‌ها به خوبی کار می‌کنه.
  • استقرار اپلیکیشن‌های MEAN Stack در سرورهای ابری: باید اپلیکیشن رو روی سرورهای ابری مستقر کنی.
  • مستندسازی کد و ارائه پشتیبانی و نگهداری مداوم: باید کدت رو مستند کنی و در صورت نیاز پشتیبانی و نگهداری ارائه بدی.

در کل، یه MEAN Stack Developer مسئول تمام مراحل توسعه وب هست و باید اپلیکیشن‌های مقیاس‌پذیر و قوی بسازه.

مهارت‌های MEAN Stack Developer

برای موفقیت در این نقش، باید یه سری مهارت‌های تخصصی داشته باشی:

  • مهارت‌های طراحی: باید مهارت‌های طراحی قوی داشته باشی تا رابط‌های کاربری کاربرپسند و جذاب بسازی. فهم اصول طراحی وب/UI خیلی مهمه.
  • حل مسئله: توسعه‌دهنده‌ها باید بتونن باگ‌ها یا مشکلات عملکردی اپلیکیشن رو به خوبی برطرف کنن. تفکر تحلیلی و حل مسئله قوی خیلی بهت کمک می‌کنه.
  • کار تیمی: توسعه‌دهنده‌ها معمولاً با تیم‌های پروژه همکاری می‌کنن. ارتباطات قوی و کار تیمی به ساخت اپلیکیشن‌های بهتر کمک می‌کنه.
  • ارتباطات: از جلسات تا مستندسازی، ارتباطات واضح نوشتاری و کلامی کمک می‌کنه تا مشکلات پروژه کمتر بشه.
  • چند وظیفگی و مدیریت زمان: علاوه بر مهارت‌های اصلی MEAN Stack، توانایی انجام چند وظیفه و مدیریت زمان برای رسیدن به ددلاین‌های توسعه خیلی مهمه.

شروع کار با MEAN Stack

حالا که با مزایای MEAN Stack آشنا شدی، بیا ببینیم چطور می‌تونی با این تکنولوژی شروع به کار کنی. برای شروع کار با MEAN Stack، ابتدا باید ابزارهای مورد نیاز رو نصب کنی. این ابزارها عبارتند از:

  • Node.js
  • MongoDB
  • Angular CLI
  • Express.js

نصب Node.js

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

node -v

نصب MongoDB

برای نصب MongoDB می‌تونی به سایت رسمی MongoDB بری و نسخه مناسب برای سیستم‌عامل‌ت رو دانلود و نصب کنی. بعد از نصب، می‌تونی با استفاده از دستور زیر MongoDB رو اجرا کنی:

mongod

نصب Angular CLI

برای نصب Angular CLI می‌تونی از دستور زیر استفاده کنی:

npm install -g @angular/cli

نصب Express.js

برای نصب Express.js می‌تونی از دستور زیر استفاده کنی:

npm install express --save

ایجاد پروژه MEAN Stack

حالا که ابزارهای مورد نیاز رو نصب کردی، بیا یه پروژه ساده MEAN Stack بسازیم. ابتدا یه دایرکتوری جدید برای پروژه‌ت ایجاد کن و وارد اون شو:

mkdir mean-project
cd mean-project

سپس با استفاده از Angular CLI یه پروژه جدید ایجاد کن:

ng new client

بعد از ایجاد پروژه Angular، یه دایرکتوری جدید برای سرور ایجاد کن:

mkdir server
cd server
npm init -y

ایجاد سرور با Express.js

حالا بیا یه سرور ساده با استفاده از Express.js بسازیم. یه فایل جدید به نام server.js ایجاد کن و کدهای زیر رو توی اون بنویس:

const express = require('express');
const app = express();
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello, 7Learn!' });
});
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

اتصال به MongoDB

حالا بیا سرورمون رو به MongoDB متصل کنیم. برای این کار باید از کتابخانه mongoose استفاده کنیم. ابتدا این کتابخانه رو نصب کن:

npm install mongoose --save

سپس کدهای زیر رو به فایل server.js اضافه کن:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mean-db', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
  console.log('Connected to MongoDB');
});

ایجاد مدل داده‌ها

حالا بیا یه مدل ساده برای کاربران بسازیم. یه فایل جدید به نام user.model.js ایجاد کن و کدهای زیر رو توی اون بنویس:

const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  age: Number,
});
const User = mongoose.model('User', userSchema);
module.exports = User;

ایجاد روت‌های API

حالا بیا روت‌های API برای مدیریت کاربران ایجاد کنیم. یه فایل جدید به نام user.routes.js ایجاد کن و کدهای زیر رو توی اون بنویس:

const express = require('express');
const router = express.Router();
const User = require('./user.model');
router.get('/users', async (req, res) => {
  const users = await User.find();
  res.json(users);
});
router.post('/users', async (req, res) => {
  const newUser = new User(req.body);
  await newUser.save();
  res.json(newUser);
});
module.exports = router;

اتصال روت‌های API به سرور

حالا بیا روت‌های API رو به سرورمون متصل کنیم. کدهای زیر رو به فایل server.js اضافه کن:

const bodyParser = require('body-parser');
const userRoutes = require('./user.routes');
app.use(bodyParser.json());
app.use('/api', userRoutes);

مثال کاربردی: ساخت یک اپلیکیشن مدیریت کارمندان با MEAN Stack

خب ، حالا می‌خوایم با هم یه پروژه واقعی رو پیاده‌سازی کنیم. هدف این آموزش ساخت یه API RESTful هست که عملیات CRUD (ایجاد، خواندن، به‌روزرسانی، حذف) رو برای یه اپلیکیشن مدیریت کارمندان پیاده‌سازی کنه. برای ذخیره‌سازی داده‌ها از یک کلاستر MongoDB Atlas استفاده می‌کنیم.

این آموزش شامل چه مواردی هست؟

  • ساخت API RESTful برای مدیریت کارمندان
  • پیاده‌سازی عملیات CRUD
  • استفاده از MongoDB Atlas برای ذخیره‌سازی داده‌ها

صفحات اپلیکیشن

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

شروع کار

برای شروع به Node.js و یک کلاستر MongoDB Atlas نیاز داری.

  • به وبسایت Node.js برو و نسخه جدید Node.js رو دانلود و نصب کن. این آموزش با نسخه 20.11.1 تست شده. برای اطمینان از نصب صحیح نسخه Node.js، دستور زیر رو در ترمینال اجرا کن:
node --version
  • راهنمای شروع به کار با Atlas رو دنبال کن و کلاستر رایگان MongoDB Atlas خودت رو راه‌اندازی کن. مطمئن شو که رشته اتصال کلاسترت رو داری چون بعداً بهش نیاز داریم.

ساخت اپلیکیشن سرور با Node.js و Express

ابتدا یه دایرکتوری برای پروژه‌مون می‌سازیم و واردش می‌شیم:

mkdir mean-stack-example
cd mean-stack-example

ایجاد دایرکتوری‌ها و فایل‌ها

دایرکتوری‌ها و فایل‌های مورد نیاز برای اپلیکیشن سمت سرور رو می‌سازیم:

mkdir server && mkdir server/src
cd server
npm init -y
touch tsconfig.json .env
cd src
touch database.ts employee.routes.ts employee.ts server.ts

نصب وابستگی‌ها

برای ساخت API و اتصال به MongoDB Atlas به چند بسته خارجی نیاز داریم. این بسته‌ها رو نصب کن:

npm install cors dotenv express mongodb
npm install --save-dev typescript @types/cors @types/express @types/node ts-node

پیکربندی TypeScript

محتوای زیر رو در فایل tsconfig.json قرار بده:

{
  "include": ["src/**/*"],
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "outDir": "./dist"
  }
}

ایجاد رابط کارمند در سمت سرور

در فایل employee.ts کد زیر رو قرار بده تا ساختار کارمند رو تعریف کنه:

import * as mongodb from "mongodb";
export interface Employee {
    name: string;
    position: string;
    level: "junior" | "mid" | "senior";
    _id?: mongodb.ObjectId;
}

اتصال به پایگاه داده

در فایل database.ts کد زیر رو قرار بده:

import * as mongodb from "mongodb";
import { Employee } from "./employee";
export const collections: {
    employees?: mongodb.Collection<Employee>;
} = {};
export async function connectToDatabase(uri: string) {
    const client = new mongodb.MongoClient(uri);
    await client.connect();
    const db = client.db("meanStackExample");
    await applySchemaValidation(db);
    const employeesCollection = db.collection<Employee>("employees");
    collections.employees = employeesCollection;
}
async function applySchemaValidation(db: mongodb.Db) {
    const jsonSchema = {
        $jsonSchema: {
            bsonType: "object",
            required: ["name", "position", "level"],
            additionalProperties: false,
            properties: {
                _id: {},
                name: {
                    bsonType: "string",
                    description: "'name' is required and is a string",
                },
                position: {
                    bsonType: "string",
                    description: "'position' is required and is a string",
                    minLength: 5
                },
                level: {
                    bsonType: "string",
                    description: "'level' is required and is one of 'junior', 'mid', 'senior'",
                    enum: ["junior", "mid", "senior"],
                },
            },
        },
    };
    await db.command({
        collMod: "employees",
        validator: jsonSchema
    }).catch(async (error: mongodb.MongoServerError) => {
        if (error.codeName === "NamespaceNotFound") {
            await db.createCollection("employees", {validator: jsonSchema});
        }
    });
}

راه‌اندازی سرور و اتصال به پایگاه داده

در فایل server.ts کد زیر رو قرار بده:

import * as dotenv from "dotenv";
import express from "express";
import cors from "cors";
import { connectToDatabase } from "./database";
dotenv.config();
const { ATLAS_URI } = process.env;
if (!ATLAS_URI) {
  console.error("No ATLAS_URI environment variable has been defined in config.env");
  process.exit(1);
}
connectToDatabase(ATLAS_URI)
  .then(() => {
    const app = express();
    app.use(cors());
    app.listen(5200, () => {
      console.log(`Server running at http://localhost:5200...`);
    });
  })
  .catch((error) => console.error(error));

اجرای اپلیکیشن

حالا بیایم اپلیکیشن رو اجرا کنیم تا ببینیم آیا همه چیز درست کار می‌کنه یا نه:

npx ts-node src/server.ts

باید خروجی زیر رو ببینی:

Server running at http://localhost:5200...

عالی! حالا آماده‌ایم تا API RESTful برای کارمندانمون رو بسازیم.

ساخت یک API RESTful

خب، حالا می‌خوایم API رو بسازیم که شامل چهار عمل اصلی CRUD (ایجاد، خواندن، به‌روزرسانی، حذف) باشه. تو این قسمت، ما اندپوینت‌های GET، POST، PUT و DELETE رو پیاده‌سازی می‌کنیم. این اندپوینت‌ها برای مدیریت اطلاعات کارمندان در دیتابیس استفاده می‌شن.

فایل employee.routes.ts رو باز کن و کد زیر رو اضافه کن:

GET /employees

این اندپوینت لیست همه کارمندان رو برمی‌گردونه.

import * as express from "express";
import { ObjectId } from "mongodb";
import { collections } from "./database";
export const employeeRouter = express.Router();
employeeRouter.use(express.json());
employeeRouter.get("/", async (_req, res) => {
    try {
        const employees = await collections?.employees?.find({}).toArray();
        res.status(200).send(employees);
    } catch (error) {
        res.status(500).send(error instanceof Error ? error.message : "Unknown error");
    }
});

اینجا از متد find() استفاده می‌کنیم و چون پارامتر خالی {} بهش می‌دیم، همه کارمندان رو برمی‌گردونه. بعدش از متد toArray() استفاده می‌کنیم تا نتیجه به صورت آرایه برگرده.

GET /employees/

این اندپوینت یک کارمند رو با استفاده از ID برمی‌گردونه.

employeeRouter.get("/:id", async (req, res) => {
    try {
        const id = req?.params?.id;
        const query = { _id: new ObjectId(id) };
        const employee = await collections?.employees?.findOne(query);
        if (employee) {
            res.status(200).send(employee);
        } else {
            res.status(404).send(`Failed to find an employee: ID ${id}`);
        }
    } catch (error) {
        res.status(404).send(`Failed to find an employee: ID ${req?.params?.id}`);
    }
});

اینجا از ObjectId برای تبدیل ID به فرمت مورد نیاز MongoDB استفاده می‌کنیم و بعدش از متد findOne() برای پیدا کردن کارمند استفاده می‌کنیم.

POST /employees

این اندپوینت یک کارمند جدید ایجاد می‌کنه.

employeeRouter.post("/", async (req, res) => {
    try {
        const employee = req.body;
        const result = await collections?.employees?.insertOne(employee);
        if (result?.acknowledged) {
            res.status(201).send(`Created a new employee: ID ${result.insertedId}.`);
        } else {
            res.status(500).send("Failed to create a new employee.");
        }
    } catch (error) {
        console.error(error);
        res.status(400).send(error instanceof Error ? error.message : "Unknown error");
    }
});

اینجا از متد insertOne() برای اضافه کردن کارمند جدید به دیتابیس استفاده می‌کنیم. در صورت موفقیت، یک پیام با کد 201 برمی‌گردونیم.

PUT /employees/

این اندپوینت یک کارمند رو به‌روزرسانی می‌کنه.

employeeRouter.put("/:id", async (req, res) => {
    try {
        const id = req?.params?.id;
        const employee = req.body;
        const query = { _id: new ObjectId(id) };
        const result = await collections?.employees?.updateOne(query, { $set: employee });
        if (result && result.matchedCount) {
            res.status(200).send(`Updated an employee: ID ${id}.`);
        } else if (!result?.matchedCount) {
            res.status(404).send(`Failed to find an employee: ID ${id}`);
        } else {
            res.status(304).send(`Failed to update an employee: ID ${id}`);
        }
    } catch (error) {
        const message = error instanceof Error ? error.message : "Unknown error";
        console.error(message);
        res.status(400).send(message);
    }
});

اینجا از updateOne() برای به‌روزرسانی کارمند استفاده می‌کنیم. در صورت موفقیت، یک پیام با کد 200 برمی‌گردونیم.

DELETE /employees/

این اندپوینت یک کارمند رو حذف می‌کنه.

employeeRouter.delete("/:id", async (req, res) => {
    try {
        const id = req?.params?.id;
        const query = { _id: new ObjectId(id) };
        const result = await collections?.employees?.deleteOne(query);
        if (result && result.deletedCount) {
            res.status(202).send(`Removed an employee: ID ${id}`);
        } else if (!result) {
            res.status(400).send(`Failed to remove an employee: ID ${id}`);
        } else if (!result.deletedCount) {
            res.status(404).send(`Failed to find an employee: ID ${id}`);
        }
    } catch (error) {
        const message = error instanceof Error ? error.message : "Unknown error";
        console.error(message);
        res.status(400).send(message);
    }
});

اینجا از deleteOne() برای حذف کارمند استفاده می‌کنیم. در صورت موفقیت، یک پیام با کد 202 برمی‌گردونیم.

ثبت روت‌ها

حالا باید سرور Express رو طوری تنظیم کنیم که از این روت‌ها استفاده کنه. ابتدا در ابتدای فایل server.ts، روت رو ایمپورت کن:

import { employeeRouter } from "./employee.routes";

بعدش، قبل از فراخوانی app.listen()، کد زیر رو اضافه کن:

app.use("/employees", employeeRouter);

حالا سرور رو مجدداً راه‌اندازی کن:

npx ts-node src/server.ts

باید همون پیام قبلی رو ببینی:

Server running at http://localhost:5200...

عالی! حالا یه API ساده برای مدیریت کارمندان ساختیم. مرحله بعدی، ساخت یک اپلیکیشن وب با استفاده از Angular هست که با این API تعامل کنه.

ساخت اپلیکیشن سمت کاربر با Angular

مرحله بعدی ساخت یک اپلیکیشن وب با استفاده از Angular هست که با API ما تعامل داشته باشه. برای این کار از Angular CLI استفاده می‌کنیم.

نصب Angular CLI

npm install -g @angular/cli

ساخت پروژه Angular

حالا یه پروژه جدید Angular به اسم client بساز:

ng new client --inline-template --inline-style --minimal --routing --style=css
cd client

این دستور یه اپلیکیشن جدید با تنظیمات مینیمال ایجاد می‌کنه و فایل‌های CSS و HTML رو به صورت خطی داخل کامپوننت‌ها قرار می‌ده.

اجرای اپلیکیشن Angular

حالا اپلیکیشن رو اجرا کن تا مطمئن بشی همه چی درسته:

ng serve -o

باید یه تب جدید تو مرورگرت باز بشه و اپلیکیشن رو نشون بده که نوشته "Welcome to client!".

نصب Angular Material

برای استایل‌دهی، از Angular Material استفاده می‌کنیم. برای نصبش، دستور زیر رو اجرا کن:

ng add @angular/material

ایجاد رابط کارمند در سمت کاربر

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

ng generate interface employee

بعد فایل src/app/employee.ts رو باز کن و کد زیر رو اضافه کن:

export interface Employee {
  name: string;
  position: string;
  level: 'junior' | 'mid' | 'senior';
  _id?: string;
}

ایجاد سرویس کارمندان

خب، حالا وقتشه که سرویس ارتباط با API رو بسازیم. تو Angular، پیشنهاد می‌شه که منطق کسب‌وکار رو از منطق نمایش جدا کنیم. برای همین، یه سرویس می‌سازیم که تمام ارتباطات با اندپوینت /employee از API رو مدیریت کنه. این سرویس توسط کامپوننت‌ها در اپلیکیشن استفاده می‌شه.

برای ایجاد سرویس، دستور زیر رو اجرا کن:

ng generate service employee

این دستور یه سرویس جدید به اسم EmployeeService تو فایل src/app/employee.service.ts می‌سازه. محتوای این فایل رو با کد زیر جایگزین کن:

import { Injectable, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Employee } from './employee';
@Injectable({
  providedIn: 'root'
})
export class EmployeeService {
  private url = 'http://localhost:5200';
  employees$ = signal<Employee[]>([]);
  employee$ = signal<Employee>({} as Employee);
  constructor(private httpClient: HttpClient) { }
  private refreshEmployees() {
    this.httpClient.get<Employee[]>(`${this.url}/employees`)
      .subscribe(employees => {
        this.employees$.set(employees);
      });
  }
  getEmployees() {
    this.refreshEmployees();
    return this.employees$();
  }
  getEmployee(id: string) {
    this.httpClient.get<Employee>(`${this.url}/employees/${id}`).subscribe(employee => {
      this.employee$.set(employee);
      return this.employee$();
    });
  }
  createEmployee(employee: Employee) {
    return this.httpClient.post(`${this.url}/employees`, employee, { responseType: 'text' });
  }
  updateEmployee(id: string, employee: Employee) {
    return this.httpClient.put(`${this.url}/employees/${id}`, employee, { responseType: 'text' });
  }
  deleteEmployee(id: string) {
    return this.httpClient.delete(`${this.url}/employees/${id}`, { responseType: 'text' });
  }
}

ما از سرویس HttpClient برای ایجاد درخواست‌های HTTP به API استفاده می‌کنیم. متد refreshEmployees() برای گرفتن لیست کامل کارمندان استفاده می‌شه و این لیست رو در سیگنالی به نام employees$ ذخیره می‌کنه که برای بقیه اپلیکیشن در دسترس هست.

پیکربندی HttpClient در Angular

سرویس HttpClient باید به اپلیکیشن اضافه بشه. برای این کار، وارد فایل src/app/app.config.ts شو و کد زیر رو اضافه کن:

import { provideHttpClient, withFetch } from '@angular/common/http';

بعدش، این فانکشن رو به لیست providers در متغیر ApplicationConfig اضافه کن:

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(withFetch()),
    // ...
  ],
};

فانکشن withFetch برای پیکربندی سرویس HttpClient برای استفاده از API fetch استفاده می‌شه.

ایجاد کامپوننت لیست کارمندان

حالا می‌خوایم یه صفحه برای نمایش لیست کارمندان بسازیم. تو Angular، کامپوننت‌ها قطعات قابل استفاده مجددی از کد هستن که می‌تونن برای نمایش ویو استفاده بشن. یه کامپوننت جدید به اسم EmployeesList می‌سازیم و اون رو به عنوان روت /employees در اپلیکیشن ثبت می‌کنیم.

برای ایجاد کامپوننت، دستور زیر رو اجرا کن:

ng generate component employees-list

فایل src/app/employees-list/employees-list.component.ts رو باز کن و محتوای زیر رو جایگزین کن:

import { Component, OnInit, WritableSignal } from '@angular/core';
import { Employee } from '../employee';
import { EmployeeService } from '../employee.service';
import { RouterModule } from '@angular/router';
import { MatTableModule } from '@angular/material/table';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
@Component({
  selector: 'app-employees-list',
  standalone: true,
  imports: [RouterModule, MatTableModule, MatButtonModule, MatCardModule],
  styles: [
    `
      table {
        width: 100%;
        button:first-of-type {
          margin-right: 1rem;
        }
      }
    `,
  ],
  template: `
    <mat-card>
      <mat-card-header>
        <mat-card-title>Employees List</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <table mat-table [dataSource]="employees$()">
          <ng-container matColumnDef="col-name">
            <th mat-header-cell *matHeaderCellDef>Name</th>
            <td mat-cell *matCellDef="let element">{{ element.name }}</td>
          </ng-container>
          <ng-container matColumnDef="col-position">
            <th mat-header-cell *matHeaderCellDef>Position</th>
            <td mat-cell *matCellDef="let element">{{ element.position }}</td>
          </ng-container>
          <ng-container matColumnDef="col-level">
            <th mat-header-cell *matHeaderCellDef>Level</th>
            <td mat-cell *matCellDef="let element">{{ element.level }}</td>
          </ng-container>
          <ng-container matColumnDef="col-action">
            <th mat-header-cell *matHeaderCellDef>Action</th>
            <td mat-cell *matCellDef="let element">
              <button mat-raised-button [routerLink]="['edit/', element._id]">
                Edit
              </button>
              <button
                mat-raised-button
                color="warn"
                (click)="deleteEmployee(element._id || '')"
              >
                Delete
              </button>
            </td>
          </ng-container>
          <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
          <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
        </table>
      </mat-card-content>
      <mat-card-actions>
        <button mat-raised-button color="primary" [routerLink]="['new']">
          Add a New Employee
        </button>
      </mat-card-actions>
    </mat-card>
  `,
})
export class EmployeesListComponent implements OnInit {
  employees$ = {} as WritableSignal<Employee[]>;
  displayedColumns: string[] = [
    'col-name',
    'col-position',
    'col-level',
    'col-action',
  ];
  constructor(private employeesService: EmployeeService) {}
  ngOnInit() {
    this.fetchEmployees();
  }
  deleteEmployee(id: string): void {
    this.employeesService.deleteEmployee(id).subscribe({
      next: () => this.fetchEmployees(),
    });
  }
  private fetchEmployees(): void {
    this.employees$ = this.employeesService.employees$;
    this.employeesService.getEmployees();
  }
}

ثبت روت کامپوننت

حالا باید این کامپوننت رو به عنوان روت در فایل src/app/app.routes.ts ثبت کنیم. محتوای این فایل رو با کد زیر جایگزین کن:

import { Routes } from '@angular/router';
import { EmployeesListComponent } from './employees-list/employees-list.component';
export const routes: Routes = [
  { path: '', component: EmployeesListComponent, title: 'Employees List' },
];

به‌روزرسانی کامپوننت اصلی

حالا فایل src/app/app.component.ts رو باز کن و محتوای زیر رو جایگزین کن:

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { EmployeesListComponent } from './employees-list/employees-list.component';
import { MatToolbarModule } from '@angular/material/toolbar';
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, EmployeesListComponent, MatToolbarModule],
  styles: [
    `
      main {
        display: flex;
        justify-content: center;
        padding: 2rem 4rem;
      }
    `,
  ],
  template: `
    <mat-toolbar>
      <span>Employees Management System</span>
    </mat-toolbar>
    <main>
      <router-outlet />
    </main>
  `,
})
export class AppComponent {
  title = 'client';
}

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

ساخت فرم افزودن کارمند

خب، تا حالا یه لیست از کارمندان داریم، ولی هنوز نمی‌تونیم کارمند جدید اضافه کنیم. بیاید یه صفحه جدید برای افزودن کارمندان ایجاد کنیم.

ایجاد فرم کارمند

برای ایجاد فرم کارمند که شامل فیلدهای نام، موقعیت شغلی و سطح هست، از ReactiveFormsModule و FormBuilder تو Angular استفاده می‌کنیم.

ابتدا یه کامپوننت به اسم EmployeeForm ایجاد کن که هم برای افزودن و هم برای ویرایش کارمندان استفاده بشه:

ng g c employee-form

محتوای فایل employee-form.component.ts رو با کد زیر جایگزین کن:

import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatRadioModule } from '@angular/material/radio';
import { MatButtonModule } from '@angular/material/button';
import { Employee } from '../employee';
@Component({
  selector: 'app-employee-form',
  standalone: true,
  imports: [
    ReactiveFormsModule,
    MatFormFieldModule,
    MatInputModule,
    MatRadioModule,
    MatButtonModule,
  ],
  styles: [
    `
      .employee-form {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        padding: 2rem;
      }
      .mat-mdc-radio-button ~ .mat-mdc-radio-button {
        margin-left: 16px;
      }
      .mat-mdc-form-field {
        width: 100%;
      }
    `
  ],
  template: `
    <form class="employee-form" autocomplete="off" [formGroup]="employeeForm" (submit)="submitForm()">
      <mat-form-field>
        <mat-label>Name</mat-label>
        <input matInput placeholder="Name" formControlName="name" required />
        <mat-error *ngIf="name.invalid">Name must be at least 3 characters long.</mat-error>
      </mat-form-field>
      <mat-form-field>
        <mat-label>Position</mat-label>
        <input matInput placeholder="Position" formControlName="position" required />
        <mat-error *ngIf="position.invalid">Position must be at least 5 characters long.</mat-error>
      </mat-form-field>
      <mat-radio-group formControlName="level" aria-label="Select an option">
        <mat-radio-button value="junior" required>Junior</mat-radio-button>
        <mat-radio-button value="mid">Mid</mat-radio-button>
        <mat-radio-button value="senior">Senior</mat-radio-button>
      </mat-radio-group>
      <button mat-raised-button color="primary" type="submit" [disabled]="employeeForm.invalid">Add</button>
    </form>
  `
})
export class EmployeeFormComponent {
  @Input() initialState: Employee | undefined;
  @Output() formValuesChanged = new EventEmitter<Employee>();
  @Output() formSubmitted = new EventEmitter<Employee>();
  employeeForm = this.formBuilder.group({
    name: ['', [Validators.required, Validators.minLength(3)]],
    position: ['', [Validators.required, Validators.minLength(5)]],
    level: ['junior', [Validators.required]],
  });
  constructor(private formBuilder: FormBuilder) {
    if (this.initialState) {
      this.employeeForm.setValue({
        name: this.initialState.name || '',
        position: this.initialState.position || '',
        level: this.initialState.level || 'junior',
      });
    }
  }
  get name() {
    return this.employeeForm.get('name')!;
  }
  get position() {
    return this.employeeForm.get('position')!;
  }
  get level() {
    return this.employeeForm.get('level')!;
  }
  submitForm() {
    this.formSubmitted.emit(this.employeeForm.value as Employee);
  }
}

اینجا از FormBuilder برای ایجاد یک فرم واکنش‌گرا با سه فیلد استفاده می‌کنیم و همچنین اعتبارسنجی‌ها رو به فرم اضافه می‌کنیم.

ایجاد کامپوننت افزودن کارمند

حالا یه کامپوننت جدید به اسم AddEmployee برای افزودن کارمند ایجاد کن:

ng generate component add-employee

محتوای فایل add-employee.component.ts رو با کد زیر جایگزین کن:

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { EmployeeFormComponent } from '../employee-form/employee-form.component';
import { Employee } from '../employee';
import { EmployeeService } from '../employee.service';
import { MatCardModule } from '@angular/material/card';
@Component({
  selector: 'app-add-employee',
  standalone: true,
  imports: [EmployeeFormComponent, MatCardModule],
  template: `
    <mat-card>
      <mat-card-header>
        <mat-card-title>Add a New Employee</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <app-employee-form (formSubmitted)="addEmployee($event)"></app-employee-form>
      </mat-card-content>
    </mat-card>
  `,
  styles: [``]
})
export class AddEmployeeComponent {
  constructor(
    private router: Router,
    private employeeService: EmployeeService
  ) {}
  addEmployee(employee: Employee) {
    this.employeeService.createEmployee(employee).subscribe({
      next: () => {
        this.router.navigate(['/']);
      },
      error: (error) => {
        alert('Failed to create employee');
        console.error(error);
      },
    });
    this.employeeService.getEmployees();
  }
}

ما از EmployeeFormComponent استفاده می‌کنیم و هر بار که AddEmployeeComponent یه فرم دریافت می‌کنه، از EmployeeService برای ایجاد کارمند جدید استفاده می‌کنه.

ایجاد کامپوننت ویرایش کارمند

حالا یه کامپوننت جدید به اسم EditEmployee برای ویرایش کارمند ایجاد کن:

ng generate component edit-employee

محتوای فایل edit-employee.component.ts رو با کد زیر جایگزین کن:

import { Component, OnInit, WritableSignal } from '@angular/core';
import { EmployeeFormComponent } from '../employee-form/employee-form.component';
import { ActivatedRoute, Router } from '@angular/router';
import { Employee } from '../employee';
import { EmployeeService } from '../employee.service';
import { MatCardModule } from '@angular/material/card';
@Component({
  selector: 'app-edit-employee',
  standalone: true,
  imports: [EmployeeFormComponent, MatCardModule],
  template: `
    <mat-card>
      <mat-card-header>
        <mat-card-title>Edit an Employee</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <app-employee-form [initialState]="employee()" (formSubmitted)="editEmployee($event)"></app-employee-form>
      </mat-card-content>
    </mat-card>
  `,
  styles: [``]
})
export class EditEmployeeComponent implements OnInit {
  employee = {} as WritableSignal<Employee>;
  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private employeeService: EmployeeService
  ) {}
  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    if (!id) {
      alert('No id provided');
    }
    this.employeeService.getEmployee(id!);
    this.employee = this.employeeService.employee$;
  }
  editEmployee(employee: Employee) {
    this.employeeService.updateEmployee(this.employee()._id || '', employee).subscribe({
      next: () => {
        this.router.navigate(['/']);
      },
      error: (error) => {
        alert('Failed to update employee');
        console.error(error);
      },
    });
  }
}

تنها تفاوت قابل توجه با AddEmployeeComponent اینه که ما از ID کارمند از URL استفاده می‌کنیم، کارمند رو از API می‌گیریم و بعد اون رو به فرم پاس می‌دیم.

افزودن ناوبری به صفحات جدید

حالا باید ناوبری به صفحات جدید رو اضافه کنیم. فایل app-routing.module.ts رو باز کن و کد زیر رو اضافه کن:

import { Routes } from '@angular/router';
import { EmployeesListComponent } from './employees-list/employees-list.component';
import { AddEmployeeComponent } from './add-employee/add-employee.component';
import { EditEmployeeComponent } from './edit-employee/edit-employee.component';
export const routes: Routes = [
  { path: '', component: EmployeesListComponent, title: 'Employees List' },
  { path: 'new', component: AddEmployeeComponent },
  { path: 'edit/:id', component: EditEmployeeComponent },
];

حالا می‌تونیم اپلیکیشن رو تست کنیم. یه کارمند جدید بساز، بعد با کلیک روی دکمه Edit، اطلاعاتش رو ویرایش کن و تغییرات رو ببین. در نهایت می‌تونی با کلیک روی دکمه Delete، کارمند رو حذف کنی.

با این مراحل، یه اپلیکیشن مدیریت کارمندان ساده با MEAN Stack ساختیم که شامل تمام عملیات CRUD هست. اگر سوال یا چالشی داشتی، من اینجا هستم تا کمک کنم!

سوالات متداول

1. آیا یادگیری MEAN Stack آسونه؟

بله، MEAN Stack بر پایه جاوااسکریپت ساخته شده که یادگیریش نسبتاً ساده و شهودی هست. استفاده از MongoDB که یه دیتابیس NoSQL هست و با ساختارهای JSON کار می‌کنه، باعث می‌شه یادگیری و استفاده از این تکنولوژی راحت‌تر باشه. البته این که چقدر سریع و آسون یاد می‌گیری به چند عامل بستگی داره:

  • تسلط بر جاوااسکریپت: چون MEAN بر پایه جاوااسکریپت هست، اگه به این زبان مسلط باشی، خیلی کمکت می‌کنه.
  • تجربه توسعه وب: اگه قبلاً تجربه کار با فریم‌ورک‌ها یا کتابخانه‌هایی مثل AngularJS، ReactJS، Vue.js یا Express.js رو داشته باشی، یادگیری MEAN برات خیلی راحت‌تر می‌شه.
  • برنامه‌نویسی ناهمگام: آشنایی با مفاهیمی مثل callbacks، promises، و async/await که در Node.js خیلی مهم هستن، بهت کمک می‌کنه.
  • دیتابیس‌های NoSQL: درک دیتابیس‌های NoSQL هم خیلی مفیده چون MongoDB یه دیتابیس شیءگرا و NoSQL هست.

البته، اگه همه این موارد رو هم ندونی، باز هم می‌تونی MEAN رو یاد بگیری چون منابع آموزشی زیادی آنلاین وجود دارن که می‌تونی ازشون استفاده کنی.

2. آیا MEAN یه راه‌حل فول استک هست؟

بله، MEAN یه راه‌حل کامل فول استک محسوب می‌شه. این استک شامل سه لایه اصلی هست: لایه نمایش (Angular.js)، لایه اپلیکیشن (Express.js و Node.js)، و لایه دیتابیس (MongoDB).

3. آیا MEAN از MERN بهتره؟

MEAN و MERN هر دو فریم‌ورک‌های ارزشمندی هستن. توسعه‌دهندگان بر اساس تخصص خودشون در AngularJS یا ReactJS، نیازهای پروژه، اندازه محیط، نیازهای عملکردی و ملاحظات مقیاس‌پذیری تصمیم می‌گیرن که از کدوم استفاده کنن.

4. آیا MEAN Stack هنوزم تقاضا داره؟

بله، تقاضا برای توسعه‌دهندگان MEAN Stack در سال 2024 بالاست و پیش‌بینی می‌شه که این تقاضا بیشتر هم بشه. به علاوه، چون نرم‌افزار MEAN هزینه کمی داره و استفاده ازش آسونه، خیلی از کسب‌وکارهای کوچک و متوسط به توسعه‌دهندگان MEAN Stack بیشتر وابسته می‌شن.

جمع‌بندی

در نهایت، استفاده از MEAN Stack می‌تونه یه انتخاب عالی برای توسعه‌دهنده‌های وب باشه. این تکنولوژی بهت اجازه می‌ده تا با یه زبان (جاوا اسکریپت) تمام بخش‌های اپلیکیشن‌ت رو بسازی و از ابزارهای یکپارچه و هماهنگ استفاده کنی. امیدوارم این مقاله بهت کمک کرده باشه تا با MEAN Stack آشنا بشی و آماده باشی تا پروژه‌های جذابت رو با این تکنولوژی بسازی.

۰ دیدگاه
ما همه سوالات و دیدگاه‌ها رو می‌خونیم و پاسخ میدیم

دوره الفبای برنامه نویسی با هدف انتخاب زبان برنامه نویسی مناسب برای شما و پاسخگویی به سوالات متداول در شروع یادگیری موقتا رایگان شد:

۲۰۰ هزار تومان رایگان
دریافت دوره الفبای برنامه نویسی