نظرات مطالب
فعال سازی قسمت ارسال فایل و تصویر ویرایشگر آنلاین RedActor در ASP.NET MVC
اگر نظرات رو مطالعه کنید، چندین نگارش از این افزونه موجود هست که خروجی‌های متفاوتی رو نیاز دارند. ضمنا بهتره این افزونه رو با یک نمونه‌ای که مدام داره به روز میشه تعویض کنید.
نظرات مطالب
استفاده از افزونه Typeahead مجموعه Twitter Bootstrap در ASP.NET MVC
آیا پیاده سازی تابع matcher افزونه typeahead با استفاده از Htmlhelper امکان پذیر است؟
یا به عبارت دیگر: آیا امکان پیاده سازی کامل این افزونه در سمت سرور وجود دارد؟ 
مطالب
مقدمه‌ای بر Docker
Docker به صورت ساده، پلتفرمی است که به سادگی قابلیت ساخت، انتقال و اجرا کردن Image‌ها را در اختیار دارد و همچنین به صورت native درون سرور‌های لینوکسی و ویندوزی اجرا میشود؛ به علاوه اینکه در محیط محلی، برای تست نیز بر روی ماشین‌های ویندوزی و مک از طریق virtual machine قابل اجراست.

دو مفهوم اساسی در محیط Docker وجود دارند که دانستن آن‌ها ضروری است: Image و Container
image عملا چیزی است که از آن برای Build یک Container استفاده می‌شود. image دارای یک سری فایل‌های لازم و اساسی است که باعث می‌شود بر روی یک Operation System اجرا شود؛ مثل Ubuntu یا Windows. بنابراین شما Application Framework خود را خواهید داشت و همچنین Databaseی که با آن کار میکند. بنابراین قابلیت استفاده از زبان‌ها و فریم ورک‌های مختلف چون Asp.net Core, Nodejs, Python و غیره را خواهد داشت. یک image به خودی خود غیر قابل استفاده است تا زمانیکه بر روی یک Container توزیع شده باشد، تا قابلیت اجرا پیدا کند. بنابراین نقطه‌ی شروع اصلی اجرایی یک برنامه با Container مربوط به آن میباشد.
به صورت خلاصه Image یک template از نوع Readonly است که ترکیبی از لایه‌های File System می‌باشد، به همراه فایل‌های share شده‌ی دیگر (از قبیل فریم ورک‌ها و ...) که میتوانند یک Docker Container Instance را تولید نمایند.
Container یک محیط امن و ایزوله است که به وسیله‌ی image ساخته شده است و میتواند اجرا، متوقف، منتقل و یا حذف شود (بطور قابل ملاحظه‌ای اجرا کردن و متوقف کردن آن سریع میباشد).


تفاوت Docker Containers و Virtual Machines

Virtual Machines همیشه بر روی Host Operation System اجرا میشوند (که می‌تواند بر روی ویندوز یا لینوکس باشد) و بعد از آن اجرای Guest OS بر روی سطحی به نام Hypervisor. پس میتوان گفت یک کپی کامل از سیستم عامل است که که بر روی hypervisor اجرا میشود و خودش نیز بر روی سخت افزار اجرا میشود. بنابراین میتوان مثل شکل زیر، یک App داشت که عملا یک سری باینری و کتابخانه است و اگر قرار باشد بر روی سیستم عامل‌های مختلفی کار کند، احتیاج به کپی کردن کل آن می‌باشد و بطور واضحی زمان و هزینه‌ی بیشتری برای بالا آوردن آن لازم است.
اما بر خلاف آن، داکر با استفاده از ابزاری به نام Docker Engine کار میکند که میتواند Container‌های مختلفی از OS‌های مختلف را اجرا نماید و نیازی به کپی گرفتن از کل سیستم عامل برای اجرای هر container نخواهد بود.


بنابراین با استفاده از ابزار‌های مجازی سازی چون Vmware، نسخه‌ی کاملی را از سیستم عامل مطبوع خود میتوان نصب و اجرا نمود؛ اما برخلاف آن با استفاده از داکر، یک نسخه‌ی کوچک از سیستم عامل، بدون وابستگی‌ها و پیچیدگی‌های نسخه‌ی اصلی در اختیار خواهد بود.
با این وجود، بوسیله داکر به راحتی میتوان تعداد زیادی از Container‌ها را به راحتی و با سرعت بالا اجرا نموده و مورد تست و ارزیابی قرار داد.


چطور Docker میتواند سریعتر از Virtual Machine‌ها عمل کند ؟

داکر از چیزی به نام Copy On Write استفاده میکند؛ به معنای کپی کردن همزمان با نوشتن. همانطور که گفته شد هر Container از یک Image ساخته میشود و عملا Imageها همان FileSystem‌های از قبل تولید شده هستند و هر کدام از لایه‌ای از کتابخانه‌ها استفاده میکنند که برای اجرای برنامه‌های کاربردی مورد استفاده قرار می‌گیرند. سرور آپاچی را در نظر بگیرید، به عنوان یک فایل image که FileSystem بر روی آن ذخیره شده‌است. با نصب Php یک لایه بر روی لایه دیگر ایجاد شده و فقط تغییرات جدید به آن اضافه خواهند شد و حال اگر بخواهید تغییری را بر روی source code خود بدهید، عملا فقط آن تغییر به Image و FileSystem اضافه خواهد شد. این معماری لایه لایه باعث تولید یک FileSystem بصورت read-only میشود که شامل لایه‌های متفاوتی است و سبب کم حجم شدن آن، بالا رفتن سرعت آن می‌شود و همچنین با استفاده از Caching، قدرت زیادی را بدان می‌بخشد.


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


بنابراین طبق شکل فوق، بحث را اینگونه خلاصه میکنیم که هر Image از ترکیبی از لایه‌هایی از نوع read-only تشکیل شده است و با اضافه شدن Container، عملا یک لایه‌ی دیگری که قابلیت read/write را دارد بر روی آن اضافه میشود و درون آن source code میتواند قرار گیرد و اینکه بر مبنای شکل زیر میبینید که قابلیت به اشتراک گذاری Image layer‌ها به Container‌های مختلف تعبیه شده است که باعث میشود لایه‌ی نصب شده بر روی سیستم، بصورت اشتراکی قابل استفاده‌ی مجدد باشد و فضای دیسک کمتری، به علاوه سرعت اجرای بالاتری را داشته باشد. هر لایه یک مقدار هش شده‌ی یکتایی را در اختیار دارد تا از لایه‌های دیگر تمیز داده شود و قابل شناسایی باشد.




داکر در شبکه چگونه کار میکند؟

ضمنا نکته‌ی قابل توجه که در مقاله‌های بعدی به صورت عملی به آن میپردازیم این است که با استفاده از داکر میتوانیم وب سرورهایی را بر روی Container‌های مختلفی داشته باشیم که همگی بر روی پورت بطور مثال 80 هستند؛ طوری که درون هر Container بدلیل ایزوله بودن پروسس‌های مخصوص Container مربوط به خود، به پورت‌های باز داخل آن شبکه دسترسی دارند و میتوانند پورت در نظر گرفته شده‌ی درون Container را با پورت دیگری بیرون Container به اصطلاح Expose نمایند.
ضمن اینکه نکته‌ی دیگری که وجود دارد، ارتباط Container‌ها با یکدیگر است. برای مثال یک Container برای Database و دیگری برای WebApp میباشد که باید به همدیگر link شده تا قابل استفاده گردند و عملا نیازی به نوشتن ip یکدیگر در این حالت وجود ندارد. البته راه‌های دیگری از قبیل Compose کردن نیز وجود دارد که در ادامه بیشتر با آن‌ها آشنا خواهیم شد.


Docker Volume چیست؟

بحث دیگری که وجود دارد، Volumeها هستند که قسمتی از FileSystem‌ها میباشند و بصورت ساده، مثال کاربردی‌اش میتواند قسمتی از یک سیستم و دایرکتوری خاصی را بر روی Container خاصی Map کردن باشد و عملا داخل آن دایرکتوری میتواند source code بوده باشد (یکی از راه‌های ممکن برای map کردن source code به container) و بر روی Container ایجاد شود.
فوایدی که با استفاده از Volume‌ها میتوان به آن رسید از قبیل موارد زیر میباشند:
قابلیت به اشتراک گذاری یک Volume بین Container‌های مختلف که به شدت میتواند قابل استفاده باشد.
Data Volume‌ها ماندگار هستند. یعنی حتی بعد از اینکه Container مربوطه را حذف نمایید، volume مربوط به آن بطور اتوماتیک حذف نمیشود (مگر اینکه خودتان دستور حذف کردن آن را وارد نمایید). پس عملا قابلیت استفاده‌ی مجدد را نیز خواهد داشت.

طبق شکل فوق ما میتوانیم درون یک container یک volume داشته باشیم. وقتی ما چیزی را درون آن مینویسیم عملا داریم در قسمت خاصی به نام Docker Host عمل write کردن را انجام میدهیم که باعث میشود داکر متوجه آن شود. وقتی اسمی را به یک Volume انتساب میدهیم همانند /var/www، در واقع یک اسم مستعار (alias) میباشد که اشاره میکند به این Docker host موجود. در ادامه بیشتر با Volume‌ها آشنا خواهیم شد. 


DockerFile و ساخت image‌ها چگونه است؟

روش دیگر برای اجرای source code در داکر، ساخت یک image اختصاصی از آن و اجرا کردن آن بر روی یک container مجزا است.  با استفاده از DockerFile میتوانید image‌های خود را build کرده که عملا هر image در آخر باید به یک سیستم عامل برسد و همانطور که گفته شد به صورت لایه‌ای کار میکنند و مراتب اجرای آن از قبیل working directory و expose کردن بر روی پورتی خاص، همچنین استفاده از Environment Variable‌ها میباشد و همچنین با استفاده از DockerHub (که نسخه‌ی enterprise نیز دارد) میتوان image‌های ساخته شده را بر روی cloud نگه داشت و همه‌ی اعضای تیم از یک image بخصوص استفاده کنند؛ برای مثال همه‌ی اعضای تیم از یک نسخه‌ی Nodejs استفاده کنند و اشتباها بر روی ماشین‌های توسعه‌ی مختلف برنامه نویسان، از نسخه‌های مختلفی استفاده نشود و همچنین روند به‌روز رسانی به سادگی انجام گیرد.


مزایای Docker برای برنامه نویسان

فرض کنید که یک App Service از Azure تهیه کرده باشید. تست‌های unit, integration, acceptance را انجام داده و با خیال راحت Container خود را از طریق برای مثال Visual studio team service بر روی App service به صورت انتشار از طریق مدل Continuous Integration و  Continuous Deployment داشته باشید. پس عملا داکر به Devops بودن محیط و چابک بودن تیم توسعه کمک شایانی کرده و فرآیند‌های سخت و زمانبر انتقال Codeها از محیط توسعه به محیط انتشار را تسریع میبخشد.
بنابراین از داکر به راحتی میتوان در محیط Production نیز استفاده کرد و مزایای فوق العاده ای را برای برنامه نویسان ارائه کرده است. بطور مثال فرض کنید در تولید نرم‌افزار یک Web server ، تعدادی Database و یک Caching server که کانفیگ کردن، اجرا و ... به صورت عادی بسیار صعب و مشکل ساز بوده را به راحتی میتوان اجرا نمود. ضمن اینکه ممکن است هر کدام از ابزارهایی که استفاده شده، فقط مخصوص سیستم عاملی خاص باشد که قاعدتا احتیاج به بالا آوردن Virtual Machine خواهید بود و در سناریو‌های خاصی مثل سیستم هایی با معماری Microservice که هر کدام از این ریز سرویس‌ها ممکن است زبان، فریم ورک، دیتابیس و ... مخصوص به خود را داشته باشند، عملا کار بسیار سخت و پر هزینه خواهد بود (ضمن اینکه استفاده‌ی همزمان از چند Virtual Machine در کنار هم در محیط توسعه، حجم زیادی از memory و disk سیستم شما را خواهد گرفت و شما را مجبور به ارتقای سیستم خود خواهد کرد!).

مشکل دیگری که Docker آن را حل کرده، Conflict‌های ورژن‌های مختلف ابزار‌های مورد استفاده است. به راحتی میتوان Containerی از Image‌ها را به صورت ایزوله با ورژن‌های مختلفی ایجاد کرد تا بطور کامل برنامه نویسان را از مشکل همیشگی به‌روزرسانی‌ها و Role-back کردن‌ها آسوده خاطر نماید. 

از آنجایی که داکر قابلیت اجرای در محیط production را نیز دارد، عملا محیط Development با محیط Production تفاوتی ندارد و این جمله‌ی معروف که «در سیستم من کار میکند اما در نسخه‌ی انتشار داده شده خیر» دیگر اتفاق نخواهد افتاد.

به راحتی میتوانید از یک Image خاص، Containerهای ایزوله‌ی متفاوتی را ساخته و همگی آنها را در کنار هم اجرا نمود و مورد تست و ارزیابی قرار داد.


Dokcer hub

مخرنی است از هزاران Image آماده از قبیل سیستم عامل، فریم ورک و... که قابلیت استفاده‌ی مجدد خواهد داشت. همچنین شما میتوانید Image‌های خود را نیز بدان اضافه نموده تا دیگران از آن استفاده نمایند. استفاده از مخزن‌های public آن رایگان میباشد. از آنجایی که Docker یک محصول متن باز و رایگان است، یک بخش از درآمد‌های آن از فروش اختصاصی مخزن‌ها در DokcerHub میباشد (چیزی شبیه به Private Repository در Github).
بیشتر از این به مفاهیم نمیپردازیم. برای مطالعه‌ی بیشتر، کتاب فوق العاده‌ی Mastering Docker را پیشنهاد میکنم. 


شروع به کار با Docker

بعد از نصب کردن نسخه‌ی رسمی Docker و باز کردن ترمینال مربوطه، اولین دستوراتی را که باید با آن آشنا باشیم، شامل موارد زیر میباشد:

لیست Image‌های کش شده‌ی بر روی سیستم:
 docker images
لیست container‌های در حال اجرای بر روی ماشین محلی:
 docker ps
بعد از تست کردن دو دستور فوق مشاهده میکنید که هیچ image و containerی بر روی سیستم شما وجود ندارد.

برای آزمایش کردن و نصب اولین image، دستور زیر را وارد میکنیم (میتوانید اطلاعات بیشتری از imageها را در dockerHub پیدا کنید). من در اینجا  kitematic/hello-world-nginx را به عنوان image از مخزن dokcerhub، بر روی سیستم خود pull کرده‌ام (این یک نسخه‌ی بسیار سبک از کانتینر nginx میباشد).
 docker pull kitematic/hello-world-nginx
بعد از اجرای دوباره‌ی دستور docker images مشاهده میکنید که image مربوطه بر روی سیستم شما نصب شده است.
حال وقت اجرای این image و توزیع آن بر روی container میباشد که با استفاده از دستور زیر است:
 docker run -p 80:80 kitematic/hello-world-nginx
پرچم p- برای مقدار دهی پورت خارجی و داخلی میباشد و بعد از آن هم که نام image مربوطه برای اجرای container میباشد (فلگ‌های خیلی بیشتر و تخصصی‌تری در رابطه با اجرا وجود دارند که در ادامه بیشتر مورد بحث قرار می‌گیرند) .

بعد از اجرای این دستور میتوانید با وارد کردن ip مربوط به virtual machine ساخته شده بر روی سیستم خود (اگر از مک یا ویندوز استفاده میکنید احتمالا 192.168.99.100 خواهد بود) که البته با دستور docker-machine ip میتوانید آن را پیدا کنید و وارد کردن آن بر روی مرورگر خود، تصویری مثل زیر را مشاهده کنید:

بدین معناست که container شما اجرا شده و قابلیت مورد استفاده قرار گرفتن را خواهد داشت. حال اگر دستور docker ps را مجددا وارد نمایید، اطلاعات این container را از نوع id, status port و غیره، مشاهده خواهید کرد.
مطالب
افزودن یک DataType جدید برای نگه‌داری تاریخ خورشیدی - 2
پیش از هرچیز به شما پیش‌نهاد می‌کنم؛ بار دیگر کد سی‌شارپ درس نخست را در پروژه‌ی خود کپی کنید و سپس Publish را بزنید. پس از ارسال آن مطلب، تغییراتی در جهت بهینه‌سازی کد دادم که به نظرم بهتر است شما نیز در پروژه‌ی خود به کار برید.

چرا از این نوع داده استفاده کنیم؟
نخستین پرسشی که ممکن است برای شما پیش بیاید این است که چرا بهتر است از این نوع داده استفاده کنیم. برای پاسخ به این پرسش باید راه‌کارهای گذشته را بررسی کنیم. معمولاً طراحان پایگاه داده‌ها برای استفاده از تاریخ خورشیدی، زمان را به صورت میلادی ثبت می‌کنند؛ سپس با یک scalar-valued function زمان درج شده را به خورشیدی تبدیل می‌کنند. در این صورت می‌توان با یک تابع کوچک دیگر بخش مربوط به ساعت را نیز از همان ستون به دست آورد. در این صورت می‌توانیم از کلیه‌ی متدهای مربوط به DateTime در SQL از جمله افزایش و کاهش و تفاضل دو تاریخ بهره برد. برخی دیگر از طراحان، ستونی از نوع (char(10 در نظر می‌گیرند و تاریخ خورشیدی را به صورت ده‌کاراکتری در آن ذخیره می‌کنند. این روش هرچند نیاز به تبدیل به خورشیدی را ندارد ولی کلیه‌ی مزایایی که در استفاده از DateTime به آن‌ها دسترسی داریم از دست می‌دهیم. افزون بر این جهت نگه‌داری زمان باید یک فیلد دیگر از نوع کاراکتری و یا در نگارش‌های نوین‌تر از نوع time تعریف کنیم. برخی دیگر از هر دو را در کنار هم استفاده می‌کنند و در واقع جهت سرعت بالاتر نمایش و بررسی داده‌ها از طریق محیط SQL Server از فیلد کاراکتری تاریخ خورشیدی و برای مقایسه و بدست آوردن ساعت از فیلد نوع DateTime استفاده می‌کنند.

از نظر فضای اشغال‌شده نوع DataTime، هشت بایت، smalldatetime (در صورت استفاده) 4 بایت و فیلد 10 کاراکتری تاریخ 10 بایت فضا اشغال می‌کند در صورتی که نوع JalaliDate با درنظر گرفتن همه‌ی مزایای انواع داده‌ی استفاده‌شده برای تاریخ، فقط 8 بایت فضا اشغال می‌کند. با استفاده از این نوع به راحتی داده‌ی تاریخ را بر اساس تقویم ایرانی اعتبارسنجی می‌کنید و بخش‌های مختلف زمان از سال تا ثانیه را با یک متد به دست می‌آورید. می‌توانید به راحتی به تاریخ خود زمانی را بیفزایید یا بکاهید و در گزارش‌ها بدون نگرانی از تبدیل درست استفاده کنید. چون کدباز است می‌توانید با کمی حوصله امکانات دیگر مد نظر خود را به آن بیفزایید و از آن در SQL بهره ببرید.

چگونه این نوع داده را حذف کنم!؟
شما می‌توانید به سادگی نوع داده‌ی ایجادشده توسط CLR را در مسیر زیر بیابید و اقدام به حذف آن نمایید:

همان‌طور که مشاهده می‌شود؛ حتی نوع داده‌ی سیستمی hierarchyid که جهت ساختار سلسله‌مراتبی مانند چارت سازمانی یا درخت تجهیزات استفاده می‌شود؛ نیز یک نوع داده‌ی CLR است.

آیا راه دیگری نیز برای افزودن این نوع داده به SQL به جز Publish کردن وجود دارد؟
مانند بسیاری دیگر از گونه‌های پروژه، در اینجا نیز شما یک فایل DLL خواهید داشت. این فایل برپایه‌ی تنظیماتی که شما در قسمت Properties پروژه‌ی خود انجام می‌دهید ساخته می‌شود. پس از تغییر مسیر فایل DLL در دستور زیر توسط یک New Query از Database خود، آن را اجرا کنید:

CREATE ASSEMBLY JalaliDate
FROM 'F:\prgJalaliDate.dll' 
WITH PERMISSION_SET = SAFE;
هم‌چنین در صورت ویرایش‌های دوباره پروژه از دستور زیر استفاده کنید:
ALTER ASSEMBLY JalaliDate
FROM 'F:\prgJalaliDate.dll'
با استفاده از دستورهای زیر می‌توانید از چگونگی درج فایل‌های افزوده شده آگاه شوید:
select * from sys.assemblies
select * from sys.assembly_files
تا اینجا SQL Server، دی‌ال‌ال مربوط به پروژه را شناخته است. برای تعریف نوع داده از دستور زیر بهره ببرید:
CREATE TYPE dbo.JalaliDate 
EXTERNAL NAME JalaliDate.[JalaliDate];
این کار همانند استفاده از گزینه‌ی Publish در Visual Studio است.
هم‌چنین چنان‌چه در SQL Server 2012 از منوی راست‌کلیک پایگاه داده‌ها روی گزینه Tasks و سپس Generate Scripts را انتخاب کنیم، از مشاهده‌ی سند ساخته شده، درخواهیم یافت که حتی دستورهای مربوط به ساخت اسمبلی CLR با تبدیل فایل به کد در Scripts وجود دارد و با اجرای آن در سروری دیگر، انتقال می‌یابد.

GO
/****** Object:  SqlAssembly [prgJalaliDate]    Script Date: 2013/04/30 08:27:00 ب.ظ ******/
CREATE ASSEMBLY [prgJalaliDate]
FROM 0x4D5A90000300000004000000FFFF0000B8000000000000 ..... بقیه‌ی کدها حذف شده
WITH PERMISSION_SET = SAFE

GO
ALTER ASSEMBLY [prgJalaliDate]
ADD FILE FROM 0x4D6963726F736F667420432F432B2B204D534620372E30300D0A1A44530..... بقیه‌ی کدها حذف شده
AS N'prgJalaliDate.pdb'

GO
/****** Object:  UserDefinedType [dbo].[JalaliDate]    Script Date: 2013/04/30 08:27:00 ب.ظ ******/
CREATE TYPE [dbo].[JalaliDate]
EXTERNAL NAME [prgJalaliDate].[JalaliDate]

GO

دنباله دارد ...
مطالب
مقدمه‌ای بر Docker، قسمت دوم
در قسمت قبلی با مفاهیم اولیه‌ی داکر آشنا شدیم و در این قسمت بیشتر به مباحث عملی آن خواهیم پرداخت. ضمن اینکه طریقه‌ی نصب داکر نیز بسیار ساده‌است و برای مطالعه‌ی بیشتر به سایت مرجع آن مراجعه بفرمایید (برای ویندوز، مک و لینوکس قسمت‌های مجزایی تعبیه شده و نصب آن آموزش داده شده‌است).
در قسمت قبلی با Volume آشنا شدیم؛ اکنون قصد داریم آن را اجرایی نموده و برنامه‌ی خود را بر روی آن اجرا نماییم. عملا با استفاده از Volume، قابلیت این را خواهید داشت که از Container ایجاد شده، با استفاده از volume، اشاره‌گری را به source code خود بر روی ماشین محلی داشته باشید و کد خود را بر روی آن اجرا نمایید.
مزایای استفاده از Volume
Volumeها بر روی Containerهای ویندوزی و لینوکسی اجرا میشوند.
قابلیت اشتراک گذاری volume بین container‌های مختلف وجود دارد.
Volumeها persisted هستند و حتی بعد از حذف container پایدار باقی می‌مانند و قابلیت استفاده‌ی مجدد را خواهند داشت.

ما طبق شکل فوق، می‌توانیم درون یک container، یک volume داشته باشیم و وقتی چیزی را درون آن می‌نویسیم، عملا داریم در قسمت خاصی به نام Docker Host عمل write کردن را انجام میدهیم که باعث میشود داکر متوجه آن شود. وقتی اسمی را به یک Volume انتساب می‌دهیم همانند /var/www، در واقع یک اسم مستعار (alias) می‌باشد که اشاره میکند به این Docker host موجود.
 
میخواهیم در این قسمت یک اپلیکیشن Nodejsِی را با استفاده از Volume بر روی Docker Container اجرا نماییم.
ابتدا دستور زیر را وارد کرده تا آخرین نسخه‌ی تصویر Nodejs را بر روی سیستم خود دریافت نمایید:
docker pull node
بعد از دریافت آن از طریق دستور زیر، لیست Image‌های cache شده بر روی سیستم خود را می‌توانید ببینید:
docker images
حال باید چنین چیزی را بر روی ترمینال خود مشاهده کنید:


در ادامه نیاز داریم یک دایرکتوری را ایجاد کرده و فایل index.js را درون آن بسازیم:

mkdir testapp
cd testapp
touch index.js
npm init
npm i express --save

یک دایرکتوری را ساختیم و همچنین express را نیز نصب نمودیم.

اکنون package.json را باز کرده و این قسمت را جایگزین کنید؛ تا با استفاده از npm start، برنامه اجرا شود:

"scripts": {
    "start": "node index"
  }

index.js را باز کرده و کد‌های زیر را وارد کنید:

const express = require('express')
const app = express()

const PORT = 3000;

app.get('/', function (req, res) {
  res.send('Hello World')
})

app.listen(PORT, function () {
  console.log(`listening on port ${PORT}!`)
})

همه چیز خیلی ساده در نظر گرفته شده است. از فریمورک express استفاده کردیم و یک سرور را بر روی پورت 3000 اجرا کرده و همچنین بر روی آدرس "/" یک سطر کد Hello World اجرا می‌شود.

خوب، فرض کنید قصد داریم با استفاده از volume، کد فوق را بر روی container اجرا کنیم.

برای اجرا شدن این کد‌ها بر روی Volume، دستور زیر را درون ترمینال خود وارد کنید:

docker run -d -p 3030:3000 -v $(pwd):/var/www -w "/var/www" node npm start

شرح دستور فوق:

دستور ساخت container با استفاده از ارگومان run

d- برای اجرا شدن container در حالت detached، باعث میشود اجرا شدن آن در حالت بک‌گراند بوده و بتوانید بر روی ترمینال مربوطه، دستورات دیگری را وارد نمایید.

p- پورت داخلی و خارجی را مشخص میکند. در اینجا پورت داخلی، 3000 و خارجی، 3030 میباشد.

آرگومان v- برای ساخت volume و (pwd)$ دایرکتوری جاری را بر روی سیستم شما، نشان خواهد داد. بعد از آن /var/www یک دایرکتوری فرضی است (هر آدرس دلخواهی را میتوانیم داشته باشیم) که قرار است بوسیله‌یdocker ساخته شود و از آن اشاره‌گری به دایرکتوری جاری بر روی ماشین محلی زده شود.

w- همان WorkingDirectory می‌باشد. بدلیل اینکه میخواهیم بر روی container به دایرکتوری که کد‌های ما وجود دارد، وارد شود.

بعد از آن اسم image ای را که قرار است از آن استفاده شود، آورده تا container ایجاد شود.

و بعد از npm start برنامه را اجرا خواهد کرد.

پس از اجرا کردن دستور فوق، container ایجاد میشود و قابلیت اجرایی دارد (با استفاده از ip و port خارجی بر روی browser میتوانیم برنامه را مشاهده کنیم).

حال با استفاده از دستور زیر لیست container‌های اجرایی را مشاهده خواهیم کرد:

docker ps

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

حتی میتوانید به راحتی درون container را با استفاده از دستور زیر مشاهده کنید:

docker exec -it 6003 bash

6003 ابتدای کلید container ایجاد شده‌است و با استفاده از bash وارد محیط command line در container ایجاد شده خواهیم شد و دسترسی کاملی خواهیم داشت.

بطور مثال برای دیدن کد‌های index.js بر روی container ایجاد شده، بعد از دستور فوق، command زیر را وارد نمایید:

cat index.js

 جالب است بدانید از آنجائیکه container از طریق volume به دایرکتوری محلی شما لینک شده‌است، به محض اینکه بر روی سیستم خود کدی را تغییر داده و دوباره دستور فوق را اجرا کنید، تغییرات را مشاهده خواهید کرد.

برای متوقف کردن container از دستور زیر باید استفاده کرد:

docker stop 6003

نکته: 6003 آی دی container است و برای اجرای مجدد آن docker start 6003

بعد از متوقف کردن container و اجرای دستور docker ps متوجه خواهید شد که دیگر Container در لیست containerهای باز نیست.

با استفاده از دستور زیر به لیست تمامی Container‌ها چه در حال اجرا و چه متوقف شده، دسترسی خواهیم داشت:

docker ps -a

برای حذف container نیز از دستور زیر استفاده میکنیم:

docker rm -v 6003

rm برای حذف container و همچنین v- برای حذف volume میباشد.

نظرات مطالب
ASP.NET MVC #7
برای توضیحات بیشتر در مورد Model و model به قسمت پنجم مراجعه کنید.
توضیح تکمیلی:
- کلاس پایه‌ای در ASP.NET MVC وجود دارد به نام  (^)WebViewPage. این کلاس حاوی تعاریف اولیه TempData، ViewBag، ViewData و ... Model است. این Model ریشه‌اش به اینجا بر می‌گردد و با حرف بزرگ شروع شده است. بنابراین در Viewهای سی شارپ Razor برای تعریف نوع مدل نیاز است بین model و شیء Model تفاوت وجود داشته باشد.
- در یک View شما هر تعداد مدل رو می‌تونید از طریق ViewBag و ViewData و غیره که در قسمت 5 توضیح داده شده، دریافت کنید و محدودیتی ندارد. اما این‌ها هیچکدام به معنای Strongly typed بودن View نیست. بنابراین برای حالت داشتن View از نوع Strongly typed، یکبار باید این نوع، تعریف شود.
البته یک راه هوشمندانه برای ارسال بیش از یک شیء به Model وجود دارد. یک کلاس تعریف کنید که خواص آن چندین شیء مورد نظر شما باشند. سپس این کلاس را به عنوان نوع Model در ابتدای View معرفی کنید. در اینجا به راحتی و به صورت Strongly typed با چند شیء می‌شود به عنوان Model کار کرد.
مطالب
AngularJS #2
بهتر است قبل از این که به ادامه‌ی آموزش بپردازم، دو نکته را متذکر شوم:
1) روند آموزشی این فریمورک از کل به جز است؛ به این معنا که ابتدا تمامی قابلیت‌های اصلی فریمورک را به صورت کلی و بدون وارد شدن به جزئیات بیان می‌کنم و پس از آن، جزئیات را در قالب مثال‌هایی واقعی بیان خواهم کرد.
2) IDE مورد استفاده بنده Visual Studio 2012 است. همچنین از ابتدا پروژه را با ASP.NET MVC شروع می‌کنم. شاید بگویید که می‌شود Angular را بدون درگیر شدن با مباحث ASP.NET MVC بیان کرد؛ اما پاسخ من این است که این مثال‌ها باید قابل پیاده‌سازی در نرم‌افزارهای واقعی باشند و یکی از بسترهای مورد علاقه‌ی من ASP.NET MVC است. اگرچه باز هم تاکید می‌کنم که کلیه‌ی مباحث ذکرشده، برای کلیه‌ی زبان‌های سمت سرور دیگر هم قابل استفاده است و هدف من در اینجا بیان یک سری چالش‌ها در ASP.NET MVC است.

نحوه‌ی دریافت AngularJS
1) NuGet Package Manager
2) دریافت از وب‌سایت angularjs.org

دریافت از طریق Nuget Package Manager
روش ارجح افزودن کتابخانه‌های جانبی در یک پروژه‌ی واقعی، استفاده از NuGet Package Manager است. دلیل آن هم بارها بیان‌شده است از جمله: باخبر شدن از آخرین به‌روزرسانی کتابخانه‌ها، دریافت وابستگی‌های کتاب‌خانه‌ی مورد نظر و نبودن محدودیت تحریم برای دریافت فایل‌ها است.
روش کار هم بسیار ساده است، کافی است که بر روی پروژه کلیک راست کرده و گزینه‌ی Manage NuGet Packages را انتخاب کنید و با جست جو angularjs نسبت به نصب آن اقدام نمایید.
اگر هم با ابزارهای گرافیکی رابطه‌ی خوبی ندارید، می‌توانید از Package Manager Console فراهم‌شده توسط NuGet استفاده کنید. کافی است در کنسول پاورشل آن عبارت زیر را تایپ کنید:
Install-Package angularjs

پس از نصب angularjs، شاهد تغییراتی در پوشه‌ی Scripts پروژه‌ی خودخواهید بود. تعداد زیادی فایل جاوا اسکریپت که با عبارت angular شروع‌شده‌اند، به این پوشه اضافه شده است. در حال حاضر ما تنها به فایل angular.js نیاز داریم و احتیاجی به فایل‌های دیگر نیست.
همچنین یک پوشه به نام i18n نیز اضافه شده است که برای مباحث Globalization و Internationalization به کار گرفته می‌شود. 
 
دریافت از سایت angularjs.org
برای دریافت Angular از وب سایت رسمی‌اش، به angularjs.org مراجعه کنید؛ اما گویا به دلیل تحریم‌ها این سایت برای IP ایران مسدود شده است (البته افرادی نیز بدون مشکل به آن دسترسی دارند). دکمه‌ی Download را فشار داده و در نهایت کلید دریافت را بزنید. اگر نسخه‌ی کامل آن را دریافت کنید، لیستی از مستندات AngularJS را نیز در فایل دریافتی، خواهید داشت. در هر صورت این روش برای استفاده از angular دریک پروژه‌ی واقعی توصیه نمی‌شود.
پس به عنوان یک best practice، همیشه کتاب‌خانه‌های جانبی را با NuGet دریافت و نصب کنید. رفع موانع تحریم‌ها، یکی از مزایای مهم آن است.
   
پس از دریافت angular،  نوشتن برنامه‌ی معروف Hello, World به وسیله‌ی آن ، می‌تواند بهترین شروع باشد؛ اما اگر اجازه بدهید، نوشتن این برنامه را در قالب توضیح قالب‌های سمت کلاینت انجام دهیم.
   
قالب‌های سمت کلاینت (Client Side Templates)
در برنامه‌های وب چند صفحه‌ای و یا اکثر وب سایت‌های معمول، داده‌ها و کدهای HTML، در سمت سرور اصطلاحا سرهم و مونتاژ شده و خروجی نهایی که HTML خام است به مرورگر کاربر ارسال می‌شود. با یک مثال بیشتر توضیح می‌دهم: در ASP.NET MVC معمولا از لحظه‌ای که کاربر صفحه‌ای را درخواست می‌کند تا زمانی که پاسخ خود را در قالب HTML می‌بیند، این فرآیند طی می‌شود: ابتدا درخواست به Controller هدایت می‌شود و سپس اطلاعات مورد نیاز از پایگاه داده خوانده‌شده و در قالب یک Model به View که یک فایل HTML ساده است، منتقل می‌شود. سپس به کمک موتور نمایشی Razor، داده‌ها در جای مناسب خود قرار می‌گیرند و در نهایت، خروجی که HTML خام است به مرورگر کلاینت درخواست‌کننده ارسال می‌شود تا در مرورگر خود نتیجه را مشاهده نماید. روال کار نیز در اکثر SPA‌های معمول و یا اصطلاحا برنامه‌های AJAX، باکمی تغییر به همین شکل است.
 اما در Angular داستان به شکل دیگری اتفاق می‌افتد؛ Angular قالب HTML و داده‌ها را به صورت جداگانه از سرور دریافت می‌کند و در مرورگر کاربر آن‌ها را سرهم و مونتاژ می‌کند. بدیهی است که در اینجا قالب، یک فایل HTML ساده و داده‌ها می‌تواند به فرم JSON باشد. در نتیجه کار سرور دیگر فراهم کردن قالب و داده‌ها برای کلاینت است و بقیه‌ی ماجرا در سمت کلاینت رخ می‌دهد.
خیلی خوب، مزیت این کار نسبت به روش‌های معمول چیست؟ اگر اجازه بدهید این را با یک مثال شرح دهم:
در بسیاری از سایت ها، ویژگی ای به نام اسکرول نامحدود وجود دارد. در همین سایت نیز دکمه ای با عنوان بیشتر در انتهای لیستی از مطالب، برای مشاهده‌ی ادامه‌ی لیست قرار گرفته است. سعی کنید پس از فشردن دکمه‌ی بیشتر، داده‌های دریافتی از سرور را مشاهده کنید. پس از انجام این کار مشاهده خواهید کرد که پاسخ سرور HTML خام است. اگر تعداد 10 پست از سرور درخواست شود، 10 بار محتوای HTML تکراری نیز دریافت خواهد شد؛ در صورتی که ساختار HTML یک پست هم کفایت می‌کرد و تنها داده‌ها در آن 10 پست متفاوتند؛ چرا که قالب کار مشخص است و فقط به ازای هر پست باید آن داده‌ها در جای مناسب خود قرار داد.
دیدگاه‌های یک پست هم به خوبی با Angular قابل پیاده سازی است. قالب HTML یک دیدگاه را برای angular تعریف کرده و داده‌های مناسب که احتمالا JSON خام است از سرور دریافت شود. نتیجه‌ی این کار هم صرفه جوی در پهنای باند مصرفی و افزایش فوق العاده‌ی سرعت است، همچنین در صورت نیاز می‌توان داده‌ها و قالب‌ها راکش کرد تا مراجعه به سرور به حداقل برسد.
 چگونگی انجام این کار در AngularJs به صورت خلاصه به این صورت است که در angular یک directive به نام ng-repeat تعریف شده است که مانند یک حلقه‌ی foreach برای HTML عمل می‌کند. شما در داخل حلقه، قالب را مشخص می‌کنید و به ازای تعداد داده‌ها، آن حلقه تکرار می‌شود و بر روی داده‌ها پیمایش صورت می‌گیرد.
البته این مثال‌ها فقط دو نمونه از کاربرد این ویژگی در دنیای واقعی بود و مطمئن باشید که در مقالات آینده مثال‌های زیادی از این موضوع را پیاده‌سازی خواهیم کرد.
بهتر است که دیگر خیلی وارد جزئیات نشویم و اولین برنامه‌ی خود را به کمک angularjs بنویسیم. این برنامه، همان برنامه‌ی معروف Hello ,World است؛ اما در این برنامه به جای نوشتن یک Hello, World ساده در صفحه، آن را با ساختار angularjs پیاده‌سازی می‌کنیم.
در داخل ویژوال استادیو یک فایل HTML ساده ایجاد کنید و کد‌های زیر را داخل آن بنویسید.
<!DOCTYPE html>
<html ng-app>
<head>
    <title>Sample 1</title>
</head>
<body>
    <div ng-controller="GreetingController">
        <p>{{greeting.text}}, World!</p>
    </div>

    <script src="../Scripts/angular.js"></script>
    <script>
        function GreetingController($scope) {
            $scope.greeting = {
                text: "Hello"
            };
        }
    </script>
</body>
</html>
سپس فایل فوق را در مرورگر اجرا کنید. بله؛ عبارت Hello, World را مشاهده خواهید کرد. یک بار دیگر خاصیت text  را در scope.greeting$ به hi تغییر بدهید و باز هم نتیجه را مشاهده کنید.
این مثال در نگاه اول خیلی ساده است، اما دنیایی از مفاهیم angular را در بر دارد. شما خواص جدیدی را برای عناصر HTML مشاهده می‌کنید: ng-app، ng-controller، آکلود‌ها و عبارت درون آن و متغیر scope$ به عنوان پارامتر.
حال بیایید ویژگی‌ها و مفاهیم جالب کدهای نوشته شده را بررسی کنیم؛ چرا که فرصت برای بررسی ng-app و بقیه‌ی موارد نا آشنا زیاد است:

- هیچ id و یا class برای عناصر html در نظر گرفته نشده تا با استفاده از آنها، رویدادی را برای عناصر مورد نظر مشخص کنیم.

- وقتی در GreetingController مقدار greeting.text را مشخص کرده ایم، باز هم هیچ رویدادی را صدا نزده و یا مشخص نکرده ایم.

- GreetingController یک کلاس ساده‌ی جاوا اسکریپت (POJO) است و از هیچ چیزی که توسط angular فراهم شده باشد، ارث بری نکرده است.

- اگر به متد سازنده‌ی کلاس GreetingController دقت کنید، متغیر scope$ به عنوان پارامتر تعریف شده است. نکته‌ی جالب این است که ما هیچ گاه به صورت دستی سازنده‌ی کلاس GreetingController را صدا نزده ایم و حتی درون سازنده هم scope$ را ایجاد نکرده ایم؛ پس چگونه توانسته ایم خاصیتی را به آن نسبت داده و برنامه به خوبی کار کند. بهتر است برای پاسخ به این سوال خودتان دست به کار شوید؛ ابتدا نام متغیر scope$ را به نام دلخواه دیگری تغییر دهید و سپس برنامه را اجرا کنید. بله برنامه دیگر کار نمی‌کند. دلیل آن چیست؟ همان طور که گفتم Angular دارای یک سیستم تزریق وابستگی توکار است و در اینجا نیز scope$ به عنوان وابستگی در سازنده‌ی  این کلاس مشخص شده است تا نمونه‌ی مناسب آن توسط angular به کلاس GreetingController ما تزریق شود؛ اما چرا به نام آن یعنی scope$ حساس است؟ به این دلیل که زبان جاوا اسکریپت یک زبان پویا است و نوع در آن مطرح نیست؛ angular مجبور است که از نام پارامترها برای تزریق وابستگی استفاده می‌کند. در مقالات آینده چگونگی عملکرد سیستم تزریق وابستگی angular را به تشریح بیان می‌کنم.

- همچنین همان طور که در مورد قبلی نیز به آن اشاره کردم، ما هیچ گاه خود دستی سازنده‌ی GreetingController را صدا نزدیم و جایی نیز نحوه‌ی صدا زدن آن را مشخص نکرده ایم.

 تا همین جا فکر کنم کاملا برای شما مشخص شده است که ساختار فریمورک Angular با تمامی کتاب خانه‌های مشابه متفاوت است و با ساختاری کاملا اصولی و حساب شده طرف هستیم. همچنین در مقالات آینده توجه شما را به قابلیت‌هایی بسیار قدرتمند‌تر جلب خواهم کرد.
   
MVC ،MVP ، MVVM و یا MVW
 در بخش اول این مقاله، الگوی طراحی پیشنهادی فریمورک Angular را MVC بیان کرده‌ام؛ اما همان طور که گفته بودم AngularJS از انقیاد داده دوطرفه (Two Way Data Binding) نیز به خوبی پشتیبانی می‌کند و به همین دلیل عده ای آن را یک MVVM Framework تلقی می‌کنند. حتی داستان به همین جا ختم نمی‌شود و عده ای آن را به چشم MVP  Framework  نیز نگاه می‌کنند. در ابتدا سایت رسمی AngularJS الگوی طراحی مورد استفاده را MVC بیان می‌نمود ولی در این چند وقت اخیر عنوانش را به MVW Framework تغییر داده است.
MVW مخفف عبارت Model View Whatever هست و کاملا مفهومش مشخص است. Model و View بخش‌های مشترک تمام الگو‌ها بودند و تنها بخش سوم مورد اختلاف توسعه دهندگان بود؛ در نتیجه انتخاب آن را بر عهده‌ی استفاده کننده قرار داده اند و تمام امکانات لازم برای پیاده‌سازی این الگو‌های طراحی را فراهم کرده اند. در طی این مقالات صرف نظر از تمام الگوهای طراحی فوق، من بیشتر بر روی MVC تمرکز خواهم کرد.
الگوی طراحی MVC در سال 1970 به عنوان بخشی از زبان برنامه نویسی Smalltalk معرفی شد و از همان ابتدا به سرعت محبوبیت زیادی در بین محیط‌های توسعه‌ی دسکتاپی از قبیل ++C و Java  که رابط کاربری گرافیکی به نوعی در آن‌ها دخیل است، پیدا کرد.
تفکر MVC این را بیان می‌کند که باید جداسازی واضح و روشنی بین مدیریت داده‌ها (Model)، منطق برنامه (Controller) و نمایش داده‌ها به کاربر (View) وجود داشته باشد و در اصل هدفش جداسازی اجزای رابط کاربری به بخش هایی مجزا است.
     
شاید این سوال برای شما پیش بیاید که چرا باید چنین الگویی را در برنامه‌ها پیاده کرد؟
احتمالا تا کنون از بین برنامه هایی که نوشته اید، رابط کاربری بیشتر از آن‌ها را نیز خودتان مجبور شده اید طراحی کنید؛ به این دلیل که برنامه‌ی شما بدون رابط کاربری قابل اجرا شدن نبوده است. اجرای برنامه‌ی شما منوط به وجود تعدادی دکمه و textbox و ... بوده است و به قولی منطق برنامه به رابط گرافیکی گره خورده بوده است. پس می‌توان گفت که پیاده‌سازی الگوی طراحی وقتی ضرورت پیدا می‌کند که رابط گرافیکی، قسمتی از برنامه‌ی شما را تشکیل دهد.
آیا با وجود زبان‌های طراحی ساده ای مثل HTML و XAML و ... احتیاجی است که برنامه نویس وقت خود را صرف طراحی رابط کاربری کند؟ مسلما خیر، چون دیگر با این امکانات یک طراح هم از پس این کار به خوبی و یا حتی بهتر بر می‌آید. دیگر وظیفه‌ی برنامه نویس نوشتن کد‌های مربوط به منطق برنامه است. کدهایی که بدون UI هم قابل تست شدن باشد و به راحتی بتوان برای آن‌ها آزمون‌های واحد نوشت. برنامه نویس باید این را در نظر بگیرد که UI وجود ندارد و حتی ممکن است هیچ گاه هم ایجاد نشود و  این کد‌ها تبدیل به یک کتابخانه شود و مورد استفاده قرار بگیرد تا در یک برنامه با رابط کاربری گرافیکی.
در MVC، روال عمومی کار به این شکل است که View داده‌ها را از Model دریافت می‌کند و به کاربر نمایش می‌دهد. وقتی که کاربر با کلیک کردن و تایپ کردن با برنامه ارتباط برقرار می‌نماید، Controller به این درخواست‌ها پاسخ می‌دهد و داده‌های موجود در Model را به روز رسانی می‌کند. در نهایت هم Model  تغییرات خود را به View منعکس می‌کند تا View آن چه را که پیش از آن نمایش می‌داده است، تغییر دهد و View را از تغییرات رخ داده آگاه نماید.
اما در برنامه‌های Angular قضیه از چه قرار است؟ در Angular، قالب HTML  یا اگر بخواهم دقیق‌تر بگویم (Document Object Model(DOM معادل View است؛ کلاس‌های جاوا اسکریپتی نقش Controller را دارند؛ و خواص اشیای جاوا اسکریپتی و یا حتی خود اشیا نقش Model را بر عهده دارند.

ساختار بخشیدن به برنامه با استفاده MVC یک مزیت مهم دیگر نیز دارد: ساختار کار کاملا مشخص است و هر کسی نمی‌تواند به صورت سلیقه ای آن را پیاده سازی کند. با یک مثال این موضوع را تشریح می‌کنم: اگر کسی پروژه‌ی بنده را که با ASP.NET MVC نوشتم، بررسی کند، اصلا احساس غریبی نمی‌کند و به راحتی می‌تواند آن را توسعه دهد. دلیل این موضوع این است که ASP.NET MVC یک ساختار مشخص را به توسعه دهندگان اجبار کرده است و هر کسی این ساختار را رعایت کند و با آن آشنا باشد، به راحتی می‌تواند با آن کار کند. توسعه دهنده می‌داندکه من Model را کجا تعریف کرده ام، Controller مربوط به هر View کجاست و در کدام قسمت با پایگاه داده ارتباط برقرار کرده‌ام؛ اما در مورد کد‌های JavaScript و سمت کلاینت چه طور؟ توسعه دهنده ای که می‌خواهد کار من را ادامه بدهد دچار وحشت می‌شود! الگوی مشخصی وجود ندارد؛ معلوم نیست که کجا DOM را دستکاری کرده‌ام، در کدام قسمت با سرور ارتباط برقرار شده و... به قول معروف با یک اسپاگتی کد تمام عیار طرف می‌شود. AngularJS این مشکل را حل نموده و ساختار خاصی را سعی کرده به شما دیکته کند و تا حد ممکن دست شما را نیز باز گذاشته است. جدا از همه‌ی اینها، برنامه‌های مبتنی بر Angular به راحتی نگه داری  و تست می‌شوند و بدون هیچ دغدغه ای آن‌ها را می‌توان توسعه داد.
   
در حاشیه
شاید در هنگام دریافت فایل angularjs و افزودن آن به پروژه‌ی خود شروع به اعتراض کرده اید که نسخه‌ی فشرده شده‌ی آن 87 کیلو بایت حجم دارد در صورتی که این حجم در کتابخانه‌های مشابه ممکن است حتی به 10 کیلوبایت هم نرسد. اگر دقت کرده باشید من در بیان AngularJS از واژه‌ی کتاب خانه استفاده نکردم و فقط از واژه‌ی فریمورک استفاده کردم. بله نمی‌شود angular را با کتاب خانه هایی مقایسه کرد که مهمترین ویژگی خود را Data Binding می‌دانند. AngularJS یک بستر کاری قدرتمند است که تمام راه حل‌های موجود را در خود جمع کرده است. تیم توسعه دهنده‌ی آن هم هیچ ادعایی ندارد و می‌گویند که ما هیچ چیزی را خودمان اختراع نکرده ایم، بلکه راه حل‌های عالی را برگزیدیم، تفکرهای خوب را ارتقا بخشیده و در فریمورک خود استفاده کردیم و حتی از ایده‌های خوب دیگر کتاب خانه‌ها هم استفاده کرده ایم. بنابر این نباید به حجم آن در مقابل توانایی هایی که دارد اعتراض کرد.
   
همچنین به نظر می‌آید که AngularJS یک فریمورک پیچیده است. ولی من همیشه بین پیچیده و پیچیده شده تفاوت قائل می‌شوم. به نظر شخصی خودم Angular به دلیل مشکلات خاص و پیچیده ای که حل می‌کند پیچیده است و پیچیده شده نیست. اگر آن را پیچیده شده حس می‌کنید، تنها دلیلش، نحوه‌ی آموزش دادن بنده است، تمام سعی خود را می‌کنم که مفاهیم را تا حد ممکن ساده بیان کنم و امیدوارم در آینده که با مثال‌های بیشتری روبرو می‌شوید، این مفاهیم به کارتان بیاید.
     
در مقاله‌ی بعدی به مفاهیم انقیاد داده، تزریق وابستگی، هدایت گر‌ها (Directives) و سرویس‌ها در AngularJS می‌پردازم.