آموزش حرفه ای انگولار از صفر تا صد با پیاده سازی یک وب اپلیکیشن شامل بخش های مختلف مانند سطوح دسترسی ، فرم های ثبت و ویرایش اطلاعات ، کارکردن با فایل ها و بخش های مهم دیگر که به شما کمک می کند در پایان دوره یک برنامه نویس حرفه ای انگولار باشید.
دو فصل اول دوره را رایگان مشاهده کنید و در صورت رضایت، دوره را تهیه بفرمایید
برای شروع به کدنویسی با Angular ما باید مطالب اولیه از انگولار را بدانیم و برای اینکه بتوانیم یک پروژه انگولار را از صفر تا صد خودمان انجام دهیم نیاز است که تسلط نسبی روی مطالب پایه داشته باشیم و از قبل تجربه انجام پروژه های تحت وب را داشته باشیم.
می دانیم که انگولار یکی از فریم ورک های معروف و محبوب در حوزه Single Page Application ها است که در حال حاضر نسخه 15 آن در حال استفاده می باشد. برای کدنویسی با آن باید زبان TypeScript را بدانیم. یادگیری تایپ اسکریپت زیاد سخت نیست و می توان با صرف زمان تسلط خوبی روی TypeScript پیدا کرد. باید بدانیم که هدف TypeScript دادن یک ساختار و اصول روی کدهای JavaScript می باشد که متغیرها و توابع تعریف شده بهتر است Type داشته باشند تا در زمان استفاده و فراخوانی آنها کمتر دچار اشتباه شویم و خطای کمتری در زمان اجرا رخ دهد.
پس نیاز است TypeScript را بلد باشیم. حالا نوبت خود انگولار است که بدانیم باید از کجا و چه سرفصل هایی را باید در انگولار یاد بگیریم.
مطالب مهم و کاربردی در انگولار این موارد می باشند :
مواردی که در بالا به صورت یک لیست مشاهده می کنید مهم ترین مطالب در انجام یک پروژه انگولار است. می خواهیم در این مقاله آشنایی مختصر و مفیدی با این بخش های پروژه انگولار داشته باشیم و کاربرد هریک را بدانیم.
ماژول ویژگی و امکان بسیار خوبی در انگولار است که هدف آن دسته بندی و pack کردن بخش های مرتبط با یکدیگر می باشد. به صورت پیش فرض در پروژه انگولار یک AppModule.ts داریم که ماژول اصلی و پیش فرض است. در ساختار داخلی یک ماژول می توان موارد مهم زیر را نام ببریم :
خوب پس وقتی یک پروژه جدید انگولار ایجاد می کنیم در پوشه app در داخل پوشه src یک فایل AppModule.ts خواهیم داشت که ماژول پیش فرض می باشد. هر فایل ماژول می تواند در کنار خود یک فایل RoutingModule هم داشته باشد که در این فایل Routing یا مسیردهی برای کامپوننت های داخل Module مسیرهایی را تعریف می کنیم. به فرض مثال مسیر products/ به کامپوننت ProductList اشاره می کند. پس عموما کنار هر ماژول فایل Routing آن را خواهیم داشت که در آن مسیرهای دلخواه و مناسب خود را به کامپوننت های موجود در آن ماژول وصل می کنیم.
تا می توانیم باید در پژوه های انگولار، بخش بندی توسط ماژول ایجاد کنیم. مثلا زیر سیستم انبار یک ماژول شود و داخل آن هم باز اگر می توانیم به ماژول های کوچکتر تقسیم کنیم. یکی از مهم ترین فواید ماژول ساختن بحث Lazy Loading می باشد. به ازای هر ماژول یک فایل js ساخته می شود. سپس این فایل js در صورت نیاز به آن بخش، از سرور دانلود می شود و روی مرورگر کاربر اجرا می شود. به این ویژگی Lazy Loading گفته می شود. عملا زمانی که به یک کامپوننت از داخل یک ماژول نیاز داریم در اولین بار فایل js مربوط به آن ماژول از سرور دانلود و بر روی مرورگر اجرا و برای دفعات بعدی cache می شود.
یک دید و آشنایی با Module و Routing به دست آوردیم. حالا نوبت کامپوننت ها می باشد.
بعد از ماژول به سراغ کامپوننت ها در انگولار می رویم. مهم ترین بخش انگولار همین کامپوننت ها است. برای ایجاد کامپوننت ها می توانیم از دستور ng g c ComponentName استفاده کنیم. اجرای این دستور باعث ایجاد 4 فایل برای کامپوننت ما خواهد شد :
این چهار فایل که با هم خواندیم، فایل های اصلی یک کامپوننت هستند که می توانند در صورت عدم نیاز هر کدام از آنها به جز فایل اصلی کامپوننت، حذف گردد.
خروجی هر کامپوننت در حالت عادی یک tag به صورت تگ های html است که به اصطلاح به آن selector یک کامپوننت گفته می شود مثل : <app-product-list></app-product-list>
برای نمایش یک کامپوننت در داخل کامپوننت دیگر تگ مربوط به آن را در بخش template کامپوننت دلخواه قرار می دهیم.
خوب تا اینجا با مفهوم ماژول و کامپوننت آشنا شدیم.
حالا به سراغ Service ها می رویم.
هدف استفاده از سرویس ها در انگولار نوشتن منطق ها و همچنین توابعی که وظیفه فراخوانی API ها را دارند، است. شما برای اینکه API های مورد نظر خودتان را برای دریافت اطلاعات از سمت سرور فراخوانی کنید می توانید به دو شکل این کار را انجام دهید.
اول اینکه در داخل خود کامپوننت یک تابع بنویسید که به کمک HttpClient از کتابخانه HttpClientModule بتوانید API خود را فراخوانی کنید. این کار ساده است ولی باعث می شود که اگر جای دیگری نیاز به همان API داشتید مجبور شوید آن قطعه کد را Copy و Paste کنید که این کار زیاد اصولی نیست. مثلا یک API که می خواهد یک DropDown یا لیست کشویی برای شما پر کند، که در اکثر فرم ها نیاز است استفاده شود. پس راه حل اول را بهتر است کمتر استفاده کنیم.
راه حل دوم و اصولی تر استفاده از Service ها است. سرویس ها در انگولار برای همین حالت ها استفاده می شوند. ما براحتی یک سرویس ایجاد می کنیم و منطق و توابع خود را داخل آنها می نویسیم و سپس در هرجایی که نیاز داشتیم از سرویس ها استفاده می کنیم. شعار یکبار بنویس و چندبار استفاده کن.
نکته ای که در استفاده از سرویس ها وجود دارد بحث Dependency Injection یا تزریق وابستگی ها است. از DI یا همان Dependency Injection فراری نباشید، مفهوم آن ساده است. به طور مثال شما یک کلاس سرویس انگولار با نام ProductService دارید. حالا آن را می خواهید در یک کامپوننت استفاده کنید. باید از کلاس خود نمونه ای بسازید. در انگولار کار نمونه سازی از Service و کنترل طول عمر نمونه ها توسط DI کنترل می شود. یعنی شما به جای new کردن یک کلاس Service آن را از طریق سازنده کلاس کامپوننت خود ایجاد یا به اصطلاح به کلاس خود تزریق می کنید. ما باید همه سرویس های خود را برای استفاده از طریق Constructor کلاس مورد نظر ایجاد کنیم. مانند کد روبرو : constructor(private productService:ProductService) – در این کد یک نمونه از کلاس ProductService ایجاد می شود و در ادامه می شود از نمونه ساخته شده استفاده کرد.
برای ایجاد سرویس ها از دستور ng g s Product استفاده می کنیم. نیازی نیست کلمه Service را در نام خود بیاوریم و خود انگولار کلمه Service را در انتهای نام Product می اندازد.
خوب متوجه شدیم که Service هم چه نقشی در انگولار دارد و چگونه می توانیم از آن استفاده کنیم.
حالا نوبت Pipe می باشد. معنی فارسی کلمه Pipe می شود لوله. حالا در انگولار Pipe چه کاری انجام می دهد؟
ما می توانیم داده های خود را به داخل یک Pipe ارسال کنیم و شکل و فرمت آن در داخل Pipe تغییر کند. مثلا تاریخ ما میلادی است و آن را داخل یک Pipe ارسال می کنیم و کاربر تاریخ را به صورت شمسی مشاهده می کند.
به صورت پیش فرض در انگولار چند Pipe داریم که البته برای ما فارسی زبان ها زیاد کاربردی ندارد. مانند Date و Currency. عموما ما از CustomPipe ها که خودمان در انگولار می نویسیم بیشتر استفاده می کنیم مانند PersianDate یا CommaSeprator ها که بین اعداد بیاید و یک کاما بیندازد.
نحوه استفاده کردن از Pipe ها در انگولار به صورت data | Pipe می باشد. متغیر data می شود داده ای که می خواهید تغییری روی آن ایجاد کنید و سپس نماد | که بین data و Pipe مورد نظر شما در Angular قرار می گیرد. از pipe های معروف در انگولار می توان json را نام برد که داده ها شما را تبدیل به json.stringify می کند.
برای ایجاد یک pipe جدید می توانیم از دستور ng g p PersianDate استفاده کنیم. با این دستور یک pipe با نام PersianDate ایجاد می شود که می توانیم کدهای داخل آن را تکمیل کرده و از آن در کامپوننت های خود استفاده کنیم.
بعد از Pipe به سراغ Directive ها می رویم. نقش Directive ها در انگولار بسیار پررنگ می باشد و ما خیلی زیاد مخصوصا در بخش Template یک کامپوننت از Directive ها استفاده می کنیم. حالا Directive ها چه کاری انجام می دهند؟
ما به کمک Directive ها می توانیم در کدهای html خود یا همان Template انگولار تغییراتی را ایجاد کنیم. مثلا یک دستور ngFor که باعث تکرار یک تکه کد html در Template کامپوننت انگولار ما می شود در اصل یک Directive می باشد. پس دستوراتی مثل ngIf یا ngFor یا دستورات این مدلی همگی از گروه Directive ها می باشند. به صورت پیش فرض ما تعداد زیادی Directive داریم که می توانیم Custom Directive ها خودمان را نیز بنویسیم. مثلا هر تگی که فلان attribute را داشت یک تغییر css روی آن اعمال شود. اگر درگیر پروژه های انگولار بشوید به مرور نقش Directive هایی که می توانید خودتان بنویسید را کاملا درک می کنید. هدف ما در اینجا آشنایی کلی شما با این مفاهیم در انگولار است.
برای ایجاد یک Directive می توانید از دستور ng g d ChangeBGColor استفاده کنید. نام Directive ای که ایجاد کردیم ChangeBGColorDirective خواهد بود.
نکته مهم این که Component ها، Pipe و Directive ها دارای یک بخش مهم در ابتدای کلاس خود با اسم دکوراتور است که یک ویژگی مهم در این دکوراتور که با @ شروع می شود وجود دارد. نام این ویژگی selector است که نام آنها را برای استفاده در جاهای دیگر مشخص می کند.
حالا باید Routing و نقش آن را در انگولار متوجه شویم. شما یک سری کامپوننت دارید و حالا می خواهید که یک منو ایجاد کنید و کاربر با کلیک روی آیتم های منو بتواند کامپوننت مورد نظر خود را مشاهده کند. برای این کار باید از Routing استفاده کنیم. به صورت پیش فرض هر ماژول می تواند یک Routing فایل داشته باشد که در داخل این Routing فایل، مشخص می کنیم که مثلا آدرس products/ به چه کامپوننتی اشاره کند. نکته خیلی مهم در Routing ها این است که به شکلی ماژول های خود را در انگولار ساخته باشیم که براحتی بتوانیم در تعریف Route های آنها از امکان و ویژگی LazyLoading یا بارگذاری در زمان مورد نیاز استفاده کنیم. پس باید این نکته را همیشه رعایت کنیم که برای هر بخش یک ماژول جدید ایجاد کنیم که در کنار ماژول جدید یا Routing فایل هم داشته باشیم. سپس این ماژول ها را در Routing اصلی یا همان AppRoutingModule به صورت LazyLoad اضافه یا import کنیم تا نسخه اولیه سایت ما سبک تر باشد و اگر کاربر روی منویی کلیک کرد در آن لحظه کد آن بخش از سمت سرور به صورت یک js فایل دریافت شود و به کاربر نمایش داده شود.
ما در Routing مباحث مهمی مانند کنترل دسترسی ها کاربر را داریم که کاربر بتواند چه مسیرهایی را ببینید و به چه مسیرهایی دسترسی نداشته باشد که عموما از کتابخانه NGXPermission استفاده می شود.
حالا سراغ Interceptor ها در انگولار می رویم. می خواهیم بدانیم نقش آنها در انگولار چیست و اگر ما آنها را بلد باشیم چقدر برخی از کارهای ما ساده می شود.
فکر کنید می خواهیم یک سامانه را به کمک انگولار پیاده سازی کنیم. API ها آن نیز پیاده سازی شده و در اختیار تیم Front قرار داده شده است. خوب این API ها عمومی نیستند که هر کس بتواند داده از آنها دریافت کند. ابتدا باید کاربر با نام کاربری و رمز عبور خود Login کند و در اصل Authenticate شود. در این حالت یک Token یا کلید در سمت سرور ایجاد می شود و در پاسخ Login برای Front ارسال می شود که بشود کلید دسترسی ما به منابع درخواستی مثلا لیست سفارشات جدید.
ما باید Token دریافتی را در همه درخواست های API خود از طریق HttpClient و Request Headers به سمت سرور ارسال کنیم تا اینکه سرور پس از چک کردن صحت Token اجازه دسترسی به منبع درخواستی را برای ما صادر کند. خوب تا اینجا Interceptor هیچ نقشی نداشت.
حالا شما فکر کنید باید در همه سرویس های خود بیاید و Token را به درخواست خود اضافه کنید. تیم انگولار برای این مدل کارها Interceptor ها یا همان Middleware را ایجاد کرده است. شما می توانید براحتی یک Interceptor ایجاد کنید و داخل آن مشخص کنید که روی همه HttpRequest ها شما بیاید و یک Request Header با عنوان Authorization با مقدار Token مورد نظر set کرده و سپس درخواست را ارسال کند.
انگار شما یک گیت ورودی یا خروجی دارید که می توانید در آن همه درخواست و پاسخ ها را قبل ارسال یا دریافت چک کنید و تغییری روی آنها اعمال کنید. این نقش را Interceptor بازی می کند و کار ما را استاندارد و ساده می کند.
برای ایجاد یک Interceptor جدید از دستور ng g interceptor MyHttp استفاده می کنیم که من عمدا نام بی ربط MyHttp را برای نام Interceptor خود انتخاب کردم. بهتر است Interceptor های خود را در انگولار در یک پوشه جداگانه ایجاد کنیم که همه Interceptor ها در یک فولدر در پوشه app کنار یکدیگر ساخته شوند.
حالا نوبت نحوه پیاده سازی فرم ها در انگولار است.
ایجاد Form ها همیشه جز مهم ترین مباحث در Front می باشد. ما باید بتوانیم توانایی پیاده سازی فرم های ساده و پیچیده را داشته باشیم. در انگولار برای کار با فرم ها دو روش وجود دارد که می خواهیم با این دو روش آشنا شویم و مزایا و معایب هر یک را بشناسیم.
روش های ایجاد فرم های در انگولار این دو هستند :
روش Template Driven برای پیاده سازی فرم ها روش ساده ولی پرهزینه ای است. ما می توانیم از امکان Two Way Binding که در انگولار وجود دارد این روش را پیاده سازی کنیم. در این مدل شما با ویژکی [(ngModel)] که برای استفاده از ngModel باید ماژول FormsModule را در ماژول جاری یا AppModule خود import کرده باشید، استفاده می کنیم. این روش ساده است چون با ngModel به یک متغیر bind می شویم و کاربر هر تغییری مثلا در Textbox ما ایجاد کند ما در سمت فایل ts خود در داخل متغیر این تغییر را خواهیم داشت.
مشکل این روش یا همان پرهزینه بودن آن این است که کاربر با تایپ هر کاراکتر یک update رو کامپوننت رخ می دهد و این در فرم های با المان زیاد می تواند منابع زیادی از سیستم کاربر گرفته و باعث کند یا لخت شدن فرم شود. مثلا کاربر به سرعت در حال تایپ است ولی صحنه آهسته این کار را مشاهده می کند. این یعنی سیستم ما درگیر کارهای اضافه زیادی در زمان تایپ کاربر می شود که یکی از دلایل مهم آن می تواند استفاده نادرست از ngModel باشد.
پس روش Template Driven برای فرم های با تعداد کنترل خیلی کم مانند فرم لاگین می تواند خوب باشد ولی برای فرم های پیچیده و بزرگ اصلا مناسب نیست. ضعف دوم روش Template Driven در انگولار این است که شما نمی توانید یک Validation خوب و جامع روی فرم خود داشته باشید.
با این توضیحات اهمیت و نقش ReactiveForms را متوجه شدیم. این که بهتر است فرم های خود را در انگولار به کمک ReactiveForms پیاده سازی کنیم. امکانات خوب و مناسب این کتابخانه باعث می شود که شما بتوانید یک فرم کامل به همراه Validation های مورد نیاز ایجاد کنید. همچنین شما می توانید فرم های تو در تو و فرم هایی که یک بخش تکرار شونده مانند سوابق شغلی در رزومه یک فرد که می تواند از دیپلم تا دکترا باشد را براحتی ایجاد کنید.
از کلاس های مهم در Reactive Forms انگولار می تواند به کلاس FormGroup اشاره کرد.
شما برای ایجاد یک فرم از FormGroup استفاده می کنید. برای ایجاد کنترل های یک Form انگولار از کلاس FormControl استفاده می شود و از کلاس Validators برای تعریف validation های مورد نیاز مانند اجباری بودن یک فیلد یا فرمت مورد نظر داده ورودی استفاده می شود.
یک کلاس FormBuilder در ReactiveForms انگولار وجود دارد که وظیفه ایجاد FormGroup را دارد و کلاس FormArray که برای ایجاد بخش های تکرار شونده فرم ها مانند سوابق شغلی می باشد.
پس ما مجموعه ای از کلاس مفید و کاربردی را در کتابخانه ReactiveForms داریم که به کمک آنها می توانیم فرم های انگولار خود را به صورت استاندارد پیاده سازی کنیم.
برای پیاده سازی فرم های خود در انگولار متوجه شدیم بهتر است از ReactiveForms استفاده کنیم. حالا می خواهیم درباره این موضوع صحبت کنیم که بهتر است از کدام کتابخانه css ای خود در پیاده سازی UI خود در انگولار استفاده کنیم.
خوب پاسخ من است این است که با هرکدام که تسلط بیشتری به آن دارید و می توانید UI زیبا همراه با UX خوب ایجاد کنید. اگر سال ها تجربه کار با Bootstrap را دارید حتما در شروع کار را Material به مشکل خواهید خورد.
مزیت Material نسبت به انگولار در این است که ظاهری جدیدتر و نزدیک به app های موبایل خواهید داشت و می توانید در پایان وب سایت خود را به صورت PWA رو گوشی های موبایل کاربران خود داشته باشید.
ولی اگر شما با Bootstrap سال ها کار کرده اید بهتر است در یک پروژه بزرگ به سراغ Material نروید. چون مانند Bootstrap هر کاری دلتان بخواهد نمی توانید براحتی انجام دهید و بعضی از تغییرات شما را حتما اذیت خواهند کرد.
این دو کتابخانه هر دو قوی و استاندارد می باشند ولی در انتخاب بین اینها اول Material و سپس Bootstrap قرار دارد. کتابخانه های دیگری هم وجود دارند که می توانند در برخی قسمت ها بهتر از این دو نیز عمل کنند.
در این مقاله هدف آشنایی و یک دید کلی با مفاهیم اصلی انگولار بود که امیدوارم برای شما مفید بوده باشد. ما همه این بخش ها و مطالب را به صورت یک دوره آموزشی مفصل آماده کرده ایم که می توانید در بخش دوره های آموزشی سایت آن را مشاهده کنید و بتوانید یک انگولار کار خوب و حرفه ای شوید.
سوالات متداول :