آشنایی با انگولار Angular JS

پس از ظهور فن آوری AJAX شاهد پیدایش Web Application های بسیاری بودیم. بسیاری از برنامه نویسان اقدام به تولید وب سایتها و وب اپلیکیشنهای گوناگون با حال و هوای نرم افزارهای تحت ویندوز و یا دیگر سیستم های عامل نمودند. منظورم از حال و هوا refresh نشدن صفحات و یا عدم استفاده از post back ها میباشد که برای کاربران وب تجربه جدیدی بود و دیگر با هر کلیک نیاز نبود زمان زیادی برای لود شدن مجدد محتوا در بروزر صرف کنند.

اتفاقی که پشت پرده روی میداد این بود که بروزرها تنها بخشهایی از صفحه که نیاز به بروزرسانی داشتند را از سرور درخواست میکرد و پس از دریافت با استفاده از javascript محتویات صفحه را آپدیت میکردند. در ابتدا بخشهای مورد نیاز کلاینت در سرور به HTML رندر میشدند و بعد برای کلاینت فرستاده میشدند. در گام بعدی برنامه نویسان بجای اینکه محتوا را در سرور به HTML تبدیل کنند داده خام را تنها از سرور میگرفتند و در سمت کلاینت اقدام به تولید HTML با استفاده از داده دریافتی میکردند.

این روش بسیار ساده و کارآمد میباشد اما برای صفحات ساده و یا تنها بخشی از صفحات. هر چه پیچیدگی صفحات وب و منطق نرم افزاری آنها پیچیده تر میشد پیاده سازی این صفحات با استفاده از AJAX به مراتب زمانبرتر و پیچیده تر از پیاده سازی آنها به صورت سنتی میشد. بسیاری از پروژه های Single Page Application یا SPA یا برنامه های تک صفحه ای ( که در آنها عملاً تنها یک صفحه توسط کلاینت لود میشود و محتوای آن یک صفحه به مرور با تعاملات گوناگون کاربر به روز رسانی میشد) به علت پیچیدگی کد سمت کلاینت و قابلیت تغییر پذیری و آپگرید پایین با شکست مواجه شدند. تمامی این دلایل باعث شد که برنامه نویسان به دنبال یک معماری جدید در سمت کلاینت باشند.

AngularJS یک فریمورک ساختاری برای وب اپلیکیشن های پویا است. این فریمورک به شما اجازه میدهد تا HTML را به عنوان زبان قالب خود انتخاب کنید و سینتاکس های HTML را برای بیان صریح و واضح اجزای نرم افزار، گسترش دهید. Data binding و dependency injection انگولار، بیشتر کدهایی را که شما که شما مجبور به نوشتن آن هستید را از بین می برد. همه ی این کارها در مرورگر انجام میشود و این باعث شده است که با همه تکنولوژی های سروری سازگاری خوبی داشته باشد.

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

عدم تطبیق امپدانس بین نرم افزار های پویا و متن های ایستا، اغلب با مراحل زیر حل می شوند:

کتابخانه : مجموعه ای از توابع است که در هنگام نوشتن برنامه های وب مفید هستند. کتابخانه یک نمونه کد آماده است و زمانی که نیاز باشد به کتابخانه رجوع میشود و تابع مناسب برای آن صدا زده میشود، مثل jQuery.
فریمورک : یک پیاده سازی خاص از یک نرم افزار تحت وب، که کد خود را در آن وارد میکنید.فریمورک آماده شده است و زمانی که به آن نیاز باشد، صدا زده میشود. مانند durandal، ember و … .
انگولار رویکرد دیگری هم دارد؛ سعی میکند که عدم تطبیق امپدانس بین متن های HTML محور و آنچه نرم افزارها برای ساختن سازه های HTML نیاز دارند را به حداقل برسانند.

انگولار به مرورگر از طریق یک ساختار که به آن رهنمود میگویند، دستورات جدید می آموزد. مانند :
Data binding.
ساختار کنترل DOM برای تکرار، پنهان کردن و نشان دادن قطعات DOM (Document Object Model)
پشتیبانی از فرم ها و اعتبار سنجی فرم ها.
اضافه کردن رفتار های جدید به المنت های DOM، همانند هندل کردن رخداد های DOM.
گروه بندی HTML به اجزای قابل استفاده مجدد.

یک راه حل سمت سرویس گیرنده کامل

انگولار تنها قطعه واحد در پازل کلی ساختن وب اپلیکیشن های سمت گیرنده نیست. این همه ی کد های DOM و AJAX که شما دستی نوشتید و تعریف کردید را هندل میکند و در داخل یک ساختار به خوبی قرار میدهد. این کار انگولار را در مورد اینکه چگونه نرم افزار های CRUD(Create, Read, Update, Delete) باید ساخته شود را خود مختار میکند. اما زمانی که خود مختار شد، سعی میکند مطمئن شود که نظر آن فقط یک نقطه شروع است و به شما به راحتی میتوانید آن را تغییر بدهید. انگولار با موارد زیر همراه میشود:
• هر چیزی که شما برای ساخت نرم افزار های CRUD در یک مجموعه ی منسجم لازم دارید : Data-binding، دستورات قالبی ساده، اعتبار سنجی فرم ها، روتینگ، deep-linking، اجزای قابل استفاده مجدد و dependency injection.
• گزارش آزمون پذیری : تست واحد ها، تست های پشت سر هم، mock ها و کنترلر تست ها.
• Seed application و طرح های دایرکتوری و اسکریپت های تستی به عنوان نقطه شروع٫

نقطه شروع شیرین انگولار

انگولار با ارائه کردن یک سطح بالاتر از مفهومات، توسعه نرم افزار ها را برای توسعه دهندگان آسان کرده است. همانند همه مفهوم ها، این نیز با میزان انعطاف پذیریش می آید. به عبارت دیگر، انگولار برای همه نرم افزار ها مناسب نیست. انگولار با روش نرم افزاری CRUD ساخته شده است. خوشبختانه نرم افزار های CRUD اکثریت وب اپلیکیشن ها را پشتیبانی میکند. برای اینکه بدانید که انگولار با چه نرم افزار هایی خوب کار میکند، به هر حال، به شما کمک میکند که بدانید کدام نرم افزار ها مناسب انگولار نیستند.

بازی ها و ویرایشگر های GUI مثال هایی از نرم افزار های فشرده و استفاده کننده از ترفند های DOM هستند. این نوع برنامه ها با نرم افزار های CRUD فرق دارند، و در نتیجه برای انگولار مناسب نیستند. در این گونه موارد بهتر است از کتابخانه هایی با سطح مفهوم پایین تری استفاده شود؛ همانند jQuery.

ذن(Zen) انگولار

انگولار بر این عقیده ساخته شده است که برای ساختن UI و ترکیب اجزای نرم افزار، کد های اعلانی بهتر از کد های دستوری هستند، در حالی که کد های دستوری برای بیان منطق کسب و کار بسیار عالی هستند.
• این ایده که دستکاری DOM را از منطق برنامه جدا کنیم، ایده خوبی است. این کار به طور چشمگیری قابلیت تست کردن کد را بالا میبرد.
• این که به تست نرم افزار به اندازه نوشتن آن اهمیت داده شود واقعا خیلی ایده خوبی است. سختی تست کردن به طور چشم گیری به ساختاری که کد نوشته میشود، ارتباط دارد.
• اینکه قسمت سمت سرویس گیرنده و قسمت سمت سرور را در یک نرم افزار از هم جدا کنید، بسیار خوب است. این کار باعث میشود که توسعه نرم افزار به صورت موازی پیش برود و اجازه استفاده مجدد را به هر دو طرف میدهد.
• در واقع این که یک فریمورک توسعه دهندگان را در کل زمان توسعه یک نرم افزار راهنمایی کند بسیار کمک بخش است : از قسمت طراحی UI، تا قسمت طراحی منطقی و تست.
• این که همیشه وظایف عمومی را بدیهی و وظایف سخت را ممکن سازید، کار بسیار خوبی است.

با انگولا ر دیگر لازم نیست کارهای زیر را انجام دهید:

Registering callbacks : کد شما را در هم ریخته میکند، و دیدن آن را مثل جنگل برای درختان میکند. پاک کردن کد های پر تکرار مانند callback ها کار خوبی به نظر میرسد. این کار به شدت مقدار کد های جاوا اسکریپت که شما باید بنویسید را کاهش میدهد و دیدن اینکه کد شما چه کاری انجام میدهد را آسان میکند.

دستکاری فایل های HTML DOM به صورت خودکار و برنامه نویسی :

دستکاری فایل های HTML DOM اساس نرم افزار های AJAX است، اما کار سنگین و ارور پذیری است. با تعریف صریح اینکه زمانی که حالت نرم افزار تغییر پیدا میکند UI وبسایت چگونه تغییر پیدا کند، نیازی به عوض کردن کدهای سطح پایین DOM نیست و انجام این وظایف از دوش شما برداشته میشود. بیشتر نرم افزار هایی که با انگولار نوشته میشود هیچ گاه نیاز به برنامه نویسی تغییر DOM ندارند، ولی اگر شما بخواهید میتوانید این کار را انجام دهید.

مرتب کردن داده به UI و از UI:

عملیات CRUD اکثر وظایف نرم افزار های AJAX را تشکیل میدهد. روند مرتب کردن داده از سرور به یک شی داخلی به صورت فرم HTML، به کاربر اجازه اصلاح و تغییر فرم، اعتبار سنجی فرم، نشان دادن ارور های اعتبار سنجی، بازگشت به مدل داخلی، و سپس بازگشت به سرور را میدهد، که باعث ساخته شدن کدهای متنی زیادی میشود. انگولار تقریبا بیشتر این متن ها را از بین میبرد، و کدهایی که روند اصلی نرم افزار را توصیف میکنند را به جای اجرای کل جزئیات، نگه میدارد.

نوشتن هزاران کد اولیه فقط برای شروع:

معمولا شما برای نوشتن یک نرم افزار AJAX ساده “Hello world” نیاز به نوشتن کدهای اولیه ای زیادی است. با انگولار شما میتوانید به راحتی نرم افزار را با استفاده از سرویس ها بوت استرپ کنید. این به شما اجازه میدهد که سریعتر از ویژگی های توسعه استفاده کنید. به عنوان یک پاداش، شما کنترل کامل بر روند مقدار دهی اولیه در تست خودکار را دریافت میکنید.

مزیت Angular نسبت به سایر فریم ورک های جاوا اسکریپت رقیب چیست؟

فریم ورک Angular دارای ویژگی های هوشمندانه ای مانند data binding دو طرفه، توانایی ایجاد تگ/ ویژگی/ کامنت های HTML دلخواه که کارایی را کپسوله می کنند و دستورهای تو کار که کارایی HTML نرمال را توسعه می دهد، می باشد. فریم ورک جاوا اسکریپت Angular بسیار چند بعدی و همه گیر می باشد. می توان از آن در پروژه اپلیکیشن های تک صفحه ای بزرگ یا در المان های بسیار کوچک نیز استفاده کرد. نیاز به تنظیمات زیادی برای شروع استفاده از دستور های آماده ی AngularJS نیست. 

نواقص فریم ورک Angular چیست؟

بزرگترین نقص فریم ورک Angular این است که راه های بسیاری برای انجام یک کار وجود دارد. وقتی که شما از Angular برای پروژه های نسبتا بزرگ استفاده کنید می کنید، یافتن بهترین راه برای انجام کارها بسیار دشوار خواهد بود. همچنین باید بسیار مراقب باشید که اگر از رویداد ها و المان های DOM به روشی غیر Angular استفاده می کنید، آنها را پاکسازی کنید تا دچار memory leak (نشت حافظه) نشوید.

مفاهیم پایه AngolarJs

در این بخش به معرفی از ویژگیهای معماری AngulaJs با استفاده از نمونه کدهای ساده خواهیم پرداخت.

Template های سمت کلاینت

برنامه های مبتنی بر وب یا همان وب اپلیکیشنها کد HTML صفحات مختلف وب را در سرور با استفاده از داده های موجود در پایگاه داده و همچنین View ها رندر میکنند و به کلاینت میفرستند. همانطور که اشاره شد بسیاری از برنامه های مبتنی بر فن آوری AJAX نیز همین کار را انجام میدهند. اما AngolarJs در این زمینه متفاوت عمل میکند به این ترتیب که قالبهای html یا همان template ها به همراه داده های استخراج شده از پایگاه داده و یا دیگر منابع داده ای به کلاینت فرستاده میشوند و در کلاینت داده ها و قالبها با هم ترکیب شده و به کاربر نمایش داده میشوند. در معماری angularJs نقش سرور تنها نگهدارنده و ارسال کننده قالبهای استاتیک و همچنین استخراج و ارسال داده از پایگاه داده میباشد و بس.

برای درک بهتر ادغام قالب با داده در سمت کلاینت توسط angularJs بهتر است یک مثال عملی ساده را با هم بررسی کنیم. برای شروع قالب HTML را ایجاد میکنیم که عملاً یک فایل ساده HTML در سرور میباشد:

?
1
2
3
4
5
6
7
8
9
10
11
< html ng-app >
< head >
    < script src="angular.js" >< /script >
    < script src="controllers.js">< /script >
< /head >
< body >
    < div ng-controller='HelloController'>
        < p>{{greeting.text}}, World< /p>
    < /div >
< /body >
< /html >

همچنین منطق برنامه را در فایل controller.js قرار میدهیم که در بخش Head قالب آنرا معرفی کرده ایم:

?
1
2
3
function HelloController($scope) {
$scope.greeting = { text: 'Hello' };
}

با اجرای این برنامه پیغام خسته کننده و همیشگی در ابتدای یادگیری هر فریم ورک و زبان انگلیسی یا همان Hello World خودمان ظاهر خواهد شد. اما چند نکته جالب توجه در رابطه با نمونه کد بالا موجود میباشد که برای هر کسی که کمی برنامه نویسی وب کار کرده باشد ایجاد سوال میکند:

  • از هیچ کلاس یا آی دی برای الصاق event listeners به html استفاده نشده است.
  • زمانی که HelloController مقدار Hello را به greeting.text میدهد ما هیچ event listener و یا callback ای برای بروزرسانی قالب ثبت نکردیم.
  • HelloController یک کلاس ساده جاوا اسکریپت هست و از هیچ کلاس دیگری به ارث نبرده است.
  • ما constructor کلاس HelloController را صدا نزدیم.

به این سوالات در طول این سری مقالات پاسخ خواهیم داد اما هدف از مطرح کردن آنها نشان دادن تفاوتهای ساختاری برنامه های angularJs با آنچه تا کنون در سمت کلاینت استفاده میکردیم میباشد.

Model View Controller یا MVC

خوب از خیر تاریخچه این مدل معماری میگذریم چون میدانم که برای درس تاریخ این مقاله را نمیخوانید. اما یه توضیح خلاصه راجع به معماری لازمه. علت محبوبیت این مدل این هست که کد شما را به سه قسمت تقسیم میکند بخش مدیریت داده بنام model، بخش منطق برنامه بنام controller و بخش نمایش داده به کاربر بنام view. این نوع معماری برای پروژه های متوسط و بزرگ از نظر کد نویسی مناسب هست و مثال استفاده از آن برای پروژه های ساده و کوچک مثل کشتن پشه با پتک میباشد. خیلی ها معتقدند که در این مدل کد نویسی بیشتری داریم انجام میدیم! که البته برای پروژه های کوچک درست میباشد.

view داده مورد نیاز خودش برای نمایش را از model دریافت میکند. زمانی که کاربر با برنامه تعامل میکند controller پاسخگوی مستقیم دستورات کاربر میباشد و مدل را تغییر میدهد و در نهایت مدل view را از تغییرات با خبر میکند و view نمایش داده را بروزرسانی میکند. این خلاصه معماری mvc میباشد.

در پروژه های angularJs مدل همان Document Object Model یا DOM میباشد که در فایلهای HTML ذخیره میشود. controller ها کلاسهای جاوا اسکریپت هستند و مدل در property های object ها ذخیره میشوند، نگفتم کلاسها چون در جاوااسکریپت برای ساخت object حتماً لازم نیست قبلش کلاس تعریف بشه! میدونم خیلی از برنامه نویس ها با تجربه در زبانهای c و java به خاطر loose type بودن جاوااسکریپت زیاد ازش خوششون نمیاد.

علت استفاده از مدل MVC در انگولار آشنایی برنامه نویسان با آن و همچنین ارائه یک مدل ذهنی مناسب برای اینکه چی کجا باید قرار بگیره اعلام شده.

Data Binding و یا اتصال مدل به view

همانطور که اشاره شد در گذشته زبانهای برنامه نویسی سمت سرور همچون PHP و ASP به ما با ترکیب رشته های HTML با داده در سمت سرور و ارسال آن به کلاینت در ایجاد رابط کاربری کمک کرده اند. سپس Jquery به ما این قابلیت را داد که تنها بخشهای مورد نیاز HTML یا DOM را با داده ترکیب کنیم و ما را از رندر کل صفحه خلاص کرد. اما یک مشکل وجود داشت و آن حجم زیاد کد نویسی برای هم فاز نگه داشتن UI یا رابط کاربری یا همون چیزی که کاربر داره میبینه با داده های موجود در property های object های جاوا اسکریپت بود. منظور از data binding نیز همین عمل میباشد هم فاز نگه داشتن مدل با view.

یکی از جاهایی که angular کار ما را خیلی ساده کرده همین بخش data binding هست که بدون هیچ کد نویسی و تنها با رعایت یکسری قواعد نانوشته اما عرف data binding به صورت خودکار برای ما انجام میشود. تنها کاری که ما باید انجام بدهیم این هست که به انگولار بگوییم کدام داده به کدام بخش از view باید map شوند و هر وقت مدل تغییر کرد view به صورت خودکار آپدیت میشود.

خودم هم دفعه اول باورم نمیشد تا اینکه این مثال را دیدم و اجرا کردم:

?
1
2
3
4
5
6
7
8
9
10
11
12
< html ng-app >
< head >
    < script src="angular.js">< /script >
    < script src="controllers.js">< /script >
< /head >
< body >
    < div ng-controller='HelloController'>
        < input ng-model='greeting.text'>
        < p>{ {greeting.text} }, World< /p >
    < /div >
< /body >
< /html >

این هم نمونه آماده اجرای کد بالا:

Hello, World

همانطور که ملاحظه میکنید همزمان با تایپ در textbox مقدار تگ p تغییر میکند و هیچ کدی برای ثبت و الصاق event listener ها و همچنین callback ها نوشته نشده است و تمامی عملیات databinding به صورت خودکار انجام میشود.

Dependency Injection یا تامین نیازمندیها

همانطور که اشاره شد در این مثال ساده خیلی کارها پشت پرده در حال انجام و شکل گیری هستند به طور مثال $scope ما ننوشتیم اما به صورت اتوماتیک در اختیار ما در کنترلر قرار میگیرد که کار اصلی databindig را انجام میدهد. به طور خلاصه کنترل ما به این object نیاز دارد (Dependency) و به صورت اتوماتیک توسط انگولار در اختیار آن قرار میگیرد و یا به آن تزریق (Injection) میشود.

در بخشهای آینده خواهیم دید که $scope تنها object ای نیست که توسط انگولار میتواند به کنترلهای ما تزریق شود. به طور مثال اگر ما بخواهیم از آدرس URL بروزر کاربر در کنترل خود استفاده کنیم میتوانیم کنترلر خود را به object ای با نام $location وابسته کنیم که این object توسط انگولار به کنترل ما تزریق میشود. مانند:

?
1
2
3
4
function HelloController($scope, $location) {
$scope.greeting = { text: 'Hello' };
// use $location for something good here...
}

این مدل به نام Law of Demeter شناخته میشود همچنین به آن قاعده کم فهمی نیز گفته میشود. شاید یه مقدار اسمش بد باشه اما منظور این هست که مثلاً در مثال بالا کار HellorController مقدار دهی اولیه به مدل میباشد و نیازی ندارد که نگران این باشد که $scope چگونه و توسط کی ساخته و به آن تزریق میشود.

Directive ها یا راهنماها

یکی از بهترین بخشهای angular این هست که به ما اجازه میدهد که قالبها یا view های خود را با استفاده از html تعریف کنیم. علت هم قابلیت بسط و گسترش html توسط انگولار هست. حالا منظور از این بسط و گسترش چیست؟ در طول مثالهای گذشته دیدید که از یکسری خصیصه جدید مانند ng-controller و ng-model برای تگهای گوناگون html استفاده کردیم، خوب این یک نوع بسط دادن html هست. همچنی شما میتوانید با استفاده از API انگولار تگهای کاملاً جدید ایجاد کنید مانند <my-menu></my-menu> هدف اصلی از ایجاد چنین directive هایی امکان استفاده مجدد از کد در view ها میباشد. اگر با Component ها در ASP.Net آشنا باشید میشه گفت تغریباً از نظر ساختاری Directive ها به ما کمک میکنند تا Component های مختلفی برای view ایجاد کنیم و به جای کد نویسی مجدد آنها تنها از تگهای حاصل از بسط HTML استفاده کنیم.