نظرات مطالب
inject$ در AngularJs
 به صورت کلی با استفاده از watch$  می‌توان تمامی تغییراتی را که به خواص ViewModel اعمال می‌شوند مشاهده کرد.
تعریف کلی آن به صورت زیر است:
$watch(watchExpression, listener, objectEquality)
»watchExpression : می‌توان نام خاصیت مورد نظر در ViewModel یا یک تابع را که قصد مشاهده تغییرات آن را داریم تعیین کنیم.
»Listener : با تغییر در مقدار watchExpression  اگر  مقدار قبلی این عبارت با مقدار فعلی آن برابر نباشد این تابع فراخوانی می‌شود.
» objectEquality : به صورت پیش فرض Angular مقادیر مورد نظر برای تغییرات را فقط از نظر Reference Equal بودن چک می‌کند. اگر بخواهیم که Angular به صورت عمقی و درختی مقادیر ابجکت‌ها را بررسی کند مقدار این پارامتر باید true شود.
در فریم ورک Angular هر زمان که عمل مقید سازی خواص ViewModel به عناصر DOM انجام می‌گیرد در واقع یک نمونه از watch$ به لیستی به نام watch list $ اضافه می‌شود. دقت کنید که صرفا تعریف در محدوده کنترلر کافی نیست بلکه باید خاصیت مورد نظر حتما مقید شود. برای مثال
app.controller('MainCtrl', function($scope) {
  $scope.foo = "Foo";
  $scope.world = "World";
});
در View نیز
Hello, {{ World }}
در کنترلر بالا دو خاصیت تعریف شده است، در حالی که در View فقط یک خاصیت مقید شده است. درنتیجه فقط یک watch$ به لیست مورد نظر اضافه شده است.
و به عنوان نکته آخر، در Angular نسخه 1.1.4 تابعی به نام watchCollection اضافه شده است که برای ردیابی تغییرات یک مجموعه مورد استفاده قرار می‌گیرد.
یک مثال در این مورد
مطالب
مفهوم Workspace در Angular
Workspace، اولین بار در انگیولار 6 معرفی شد. Angular Workspace به شما اجازه می‌دهد کل web application خود را به چندین پروژه‌ی کوچکتر سازماندهی کنید. بیشتر پروژه‌های کوچک انگیولار تنها شامل یک یا دو پروژه، به ازای هر Workspace می‌باشند. برای مثال وقتی شما یک پروژه‌ی جدید انگیولار را با Angular CLI ایجاد می‌کنید، در این حالت Workspace شامل یک app  واقعی و یک پروژه e2e tests می‌باشد. 

مستندات انگیولار یک پروژه را به صورت زیر توصیف می‌کند: 
A set of files that comprise a standalone app, a library, or a set of end-to-end (e2e) tests.


درست همانند مفهوم یک کتابخانه در توسعه نرم افزار، یک کتابخانه اشاره دارد به مجموعه‌ای از کد‌های با قابلیت استفاده‌ی مجدد که می‌توانند بین پروژه‌های مختلف به اشتراک گذاشته شوند؛ هم چنین Angular CLI این کار را برای شما آسان می‌کند تا کتابخانه خودتان را در یک مرکز ثبت مثل npm  انتشار دهید تا توسط دیگر توسعه دهندگان استفاده شود.
نوع Application اشاره به یک Application مستقل انگیولار دارد.    


Create Empty Workspaces  

در انگیولار 7 یک CLI option جدید ( create-application-- ) معرفی شد که شما می‌توانید با اضافه کردن این option به دستور ng new، سبب ایجاد یک Workspace خالی شوید. این option  با دستور ng new استفاده می‌شود و می‌تواند مقدار true یا false را دریافت کند که به صورت پیش فرض به true  تنظیم شده است. بنابراین وقتی شما یک پروژه‌ی جدید را ایجاد می‌کنید، سبب ایجاد یک پروژه‌ی اولیه انگیولار در Workspace هستید؛ همچنین می‌توانید create-application-- را به false تنظیم کنید تا CLI یک پروژه اولیه انگیولار را در Workspace  ایجاد نکند .

اکنون اجازه دهید آن را در عمل ببینیم: 
مطمئن شوید که نگارش انگیولار شما، 7 یا بالاتر باشد:
ng --version

Command Prompt را باز کرده و سپس درستور زیر را در آن اجرا کنید:
ng new angular-apps --create-application=false
سپس Angular CLI این هشدار را به شما می‌دهد که آیا تمایل دارید، Angular routing را اضافه کنید و همچنین از کدام stylesheet format تمایل دارید که استفاده کنید؛ سپس فایل‌های زیر تولید خواهند شد:  
angular-apps/README.md
angular-apps/angular.json
angular-apps/package.json
angular-apps/tsconfig.json
angular-apps/tslint.json
angular-apps/.editorconfig
angular-apps/.gitignore
و همچنین CLI تمام وابستگی‌های انگیولار را در یک پوشه به نام node_modules نصب خواهد کرد.


اکنون به Command Prompt برگردیم و وارد Angular Workspace خودمان شویم:
cd angular-apps

در ادامه یک پروژه جدید را با دستور زیر ایجاد می‌کنیم:
ng generate application admin
دستور بالا سبب ایجاد دو پروژه می‌شود ( admin  و admin-e2e )، در پوشه Projects. 
 همچنین می‌توانید یک کتابخانه را در Workspace خود با استفاده از دستور زیر ایجاد کنید:
ng generate library ngx-qrcode
ngx-qrcode نام کتابخانه می‌باشد. این کتابخانه در پوشه projects، درست مثل مابقی Application ها اضافه خواهد شد. 
بعد از ایجاد کردن چندین Application بدون Application پیش فرض برای Workspace خود، می‌توانید اقدام به ایجاد modules ، service ، components  و ... در یک پروژه مشخص با استفاده از project option-- کنید. 

برای نمونه یک سرویس را در پروژه admin ایجاد می‌کنیم:
ng generate service auth --project=admin
که سبب ایجاد دو فایل زیر می‌شود:
projects/admin/src/app/auth.service.spec.ts
projects/admin/src/app/auth.service.ts

Serving Specific Apps in Your Workspace 

جهت به خدمت گرفتن یک Application مشخص در Workspace دستور زیر را اجرا کنید:
ng serve admin
admin نام Application شما می‌باشد که می‌خواهید آن را به خدمت بگیرید. 


نکته
اگر در Command Prompt دستور زیر را وارد کنید: 
ng new
سریعا هشدار زیر را به شما می‌دهد:
What name would you like to use for the new workspace and initial project?
از شما می‌خواهد که نام Workspace  مورد نظرتان را وارد کنید و بعد از آن همان دو هشدار Routing و stylesheet format  می‌باشد که سبب ایجاد یک پروژه اولیه انگیولار در Workspace می‌شود.


نتیجه گیری 
در این مطلب متوجه مفهوم Angular Workspace و روش ایجاد کردن یک Workspace خالی شدیم و همچنین چگونه یک Application و یک Library را در یک Workspace   ایجاد کنیم. 

مطالب
مدیریت پیشرفته‌ی حالت در React با Redux و Mobx - قسمت اول - Redux چیست؟
Redux و Mobx، کتابخانه‌های کمکی هستند برای مدیریت حالت برنامه‌های پیچیده‌ی React. هرچند React به صورت توکار به همراه امکانات مدیریت حالت است، اما این کتابخانه‌ها مزایای ویژه‌ای را به آن اضافه می‌کنند. در این سری ابتدا کتابخانه‌ی Redux را به صورت خالص و مجزای از React بررسی می‌کنیم. از این کتابخانه در برنامه‌های Angular و Ember هم می‌توان استفاده کرد و به صورت اختصاصی برای React طراحی نشده‌است. سپس آن‌را به برنامه‌های React متصل می‌کنیم. در آخر کتابخانه‌ی محبوب دیگری را به نام Mobx بررسی می‌کنیم که برای مدیریت حالت، اصول برنامه نویسی شیءگرا و همچنین Reactive را با هم ترکیب می‌کند و این روزها در برنامه‌های React، بیشتر از Redux مورد استفاده قرار می‌گیرد.


چرا به ابزارهای مدیریت حالت نیاز داریم؟

به محض رد شدن از مرز پیاده سازی امکانات اولیه‌ی یک برنامه، نیاز به ابزارهای مدیریت حالت نمایان می‌شوند؛ خصوصا زمانیکه نیاز است با اطلاعات قابل توجهی سر و کار داشت. مهم‌ترین دلیل استفاده‌ی از یک ابزار مدیریت حالت، مدیریت منطق تجاری برنامه است. منطق نمایشی برنامه مرتبط است به نحوه‌ی نمایش اجزای آن در صفحه؛ مانند نمایش یک صفحه‌ی مودال، تغییر رنگ عناصر با عبور کرسر ماوس از روی آن‌ها و در کل منطقی که مرتبط و یا وابسته‌ی به هدف اصلی برنامه نیست. از سوی دیگر منطق تجاری برنامه مرتبط است با مدیریت، تغییر و ذخیره سازی اشیاء تجاری مورد نیاز آن؛ مانند اطلاعات حساب کاربری شخص و دریافت اطلاعات برنامه از یک API که مختص به برنامه‌ی خاص ما است و به همین دلیل نیاز به ابزاری برای مدیریت بهینه‌ی آن وجود دارد. برای مثال اینکه در کجا باید منطق تجاری و نمایشی را به هم متصل کرد، می‌تواند چالش بر انگیر باشد. چگونه باید اطلاعات کاربر را ذخیره کرد؟ چگونه React باید متوجه شود که اطلاعات ما تغییر کرده‌است و در نتیجه‌ی آن کامپوننتی را مجددا رندر کند؟ یک ابزار مدیریت حالت، تمام این مسایل را به نحو یک‌دستی در سراسر برنامه، مدیریت می‌کند.
اگر از یک ابزار مدیریت حالت استفاده نکنیم، مجبور خواهیم شد تمام اطلاعات منطق تجاری را در داخل state کامپوننت‌ها ذخیره کنیم که توصیه نمی‌شود؛ چون مقیاس پذیر نیست. برای مثال فرض کنید قرار است تمام اطلاعات state را داخل یک کامپوننت ذخیره کنیم. هر زمانیکه بخواهیم این state را از طریق یک کامپوننت فرزند تغییر دهیم، نیاز خواهد بود این اطلاعات را به والد آن کامپوننت ارسال کنیم که اگر از تعداد زیادی کامپوننت تو در تو تشکیل شده باشد، زمانبر و به همراه کدهای تکراری زیادی خواهد بود. همچنین اینکار سبب رندر مجدد کل برنامه با هر تغییری در state آن می‌شود که غیرضروری بوده و کارآیی برنامه را کاهش می‌دهد. به علاوه در این بین مشخص نیست هر قسمت از state، از کدام کامپوننت تامین شده‌است. به همین جهت نیاز به روشی برای مدیریت حالت در بین کامپوننت‌های برنامه وجود دارد.


داشتن تنها یک محل برای ذخیره سازی state در برنامه

همانطور که در قسمت 8 ترکیب کامپوننت‌ها در سری React 16x بررسی کردیم، هر کامپوننت در React، دارای state خاص خودش است و این state از سایر کامپوننت‌ها کاملا مستقل و ایزوله‌است. این مورد با بزرگ‌تر شدن برنامه و برقراری ارتباط بین کامپوننت‌ها، مشکل ایجاد می‌کند. برای مثال اگر بخواهیم دکمه‌ای را در صفحه قرار داده و توسط این دکمه درخواست صفر شدن مقدار هر کدام از شمارشگرها را صادر کنیم، با صفر کردن value هر کدام از این کامپوننت‌ها، اتفاقی رخ نمی‌دهد. چون state محلی این کامپوننت‌ها، با سایر اجزای صفحه به اشتراک گذاشته نمی‌شود و باید آن‌را تبدیل به یک controlled component کرد، بطوریکه دارای local state خاص خودش نیست و تمام داده‌های دریافتی را از طریق this.props دریافت می‌کند و هر زمانیکه قرار است داده‌ای تغییر کند، رخ‌دادی را به والد خود صادر می‌کند. بنابراین این کامپوننت به طور کامل توسط والد آن کنترل می‌شود. تازه این روش در مورد کامپوننت‌هایی صدق می‌کند که رابطه‌ی والد و فرزندی بین آن‌ها وجود دارد. اگر چنین رابطه‌ای وجود نداشت، باید state را به یک سطح بالاتر انتقال داد. برای مثال باید state کامپوننت Counters را به والد آن که کامپوننت App است، منتقل کرد. پس از آن چون کامپوننت‌های ما، از کامپوننت App مشتق می‌شوند، اکنون می‌توان این state را به تمام فرزندان App توسط props منتقل کرد و به اشتراک گذاشت. این مورد هم مانند مثال انتقال اطلاعات کاربر لاگین شده‌ی به سیستم، به تمام زیر قسمت‌های برنامه، نیاز به ارسال اطلاعات از طریق props یک کامپوننت، به کامپوننت بعدی را دارد و به همین ترتیب برای مابقی که به props drilling مشهور است و روش پسندیده‌ای نیست.


Redux چیست؟ ذخیره سازی کل درخت state یک برنامه، در یک محل. به این ترتیب به یک شیء جاوا اسکریپتی بزرگ خواهیم رسید که در برگیرنده‌ی تمام state برنامه‌است. یکی از مزایای آن امکان serialize و deserialize کل این شیء، به سادگی است. برای مثال توسط متد JSON.stringify می‌توان آن‌را در جائی ذخیره کرد و سپس آن‌را به صورت یک شیء جاو اسکریپتی در زمانی دیگر بازیابی کرد. یکی از مزایای آن، امکان بازیابی دقیق شرایط کاربری است که دچار مشکل شده‌است و سپس دیباگ و رفع مشکل او، در زمانی دیگر.


تاریخچه‌ای از سیستم‌های مدیریت حالت

همه چیز با AngularJS 1x شروع شد که از data binding دو طرفه پشتیبانی می‌کرد. هرچند این روش برای همگام نگه داشتن View و مدل برنامه، مفید است، اما در Viewهای پیچیده، برنامه را کند می‌کند. در همین زمان فیس‌بوک، روش مدیریت حالتی را به نام Flux ارائه داد که از data binding یک طرفه پشتیبانی می‌کرد. به این معنا که در این روش، همواره اطلاعات از View به مدل، جریان پیدا می‌کند. کار کردن با آن ساده‌است؛ چون نیازی نیست حدس زده شود که اکنون جریان اطلاعات از کدام سمت است. اما مشکل آن عدم هماهنگی model و view، در بعضی از حالات است. Flux از این جهت به وجود آمد که مدیریت حالت در برنامه‌های React آن زمان، پیچیده بود و مقیاس پذیری کمی داشت (پیش از ارائه‌ی Context و Hooks). در کل Flux صرفا یکسری الگوی مدیریت حالت را بیان می‌کند و یک کتابخانه‌ی مجزا نیست. بر مبنای این الگوها و قراردادها، می‌توان کتابخانه‌های مختلفی را ایجاد کرد. از این رو در سال 2015، کتابخانه‌های زیادی مانند Reflux, Flummox, MartyJS, Alt, Redux و غیره برای پیاده سازی آن پدید آمدند. در این بین، کتابخانه‌ی Redux ماندگار شد و پیروز این نبرد بود!


توابع خالص و ناخالص (Pure & Impure Functions)

پیش از شروع بحث، نیاز است با یک‌سری از واژه‌ها مانند توابع خالص و ناخالص آشنا شد. این نکات از این جهت مهم هستند که Redux فقط با توابع خالص کار می‌کند.
توابع خالص: تعدادی آرگومان را دریافت کرده و بر اساس آن‌ها، مقداری را باز می‌گردانند.
// Pure
const add = (a, b) => {
  return a + b;
}
در اینجا یک تابع خالص را مشاهده می‌کنید که a و b را دریافت کرده و بر این اساس، یک خروجی کاملا مشخص را بازگشت می‌دهد.

توابع ناخالص: این نوع توابع سبب تغییراتی در متغیرهایی خارج از میدان دید خود می‌شوند و یا به همراه یک سری اثرات جانبی (side effects) مانند تعامل با دنیای خارج (وجود یک console.log در آن تابع و یا دریافت اطلاعاتی از یک API خارجی) هستند.
// Impure
const b;

const add = (a) => {
  return a + b;
}
تابع تعریف شده‌ی در اینجا ناخالص است؛ چون با اطلاعاتی خارج از میدان دید خود مانند متغیر b، تعامل دارد. این تعامل با دنیای خارج، حتی در حد نوشتن یک console.log:
// Impure
const add = (a, b) => {
  console.log('lolololol');
  return a + b;
}
یک تابع خالص را تبدیل به یک تابع ناخالص می‌کند و یا نمونه‌ی دیگر این تعاملات، فراخوانی سرویس‌های backend در برنامه هستند که یک تابع را ناخالص می‌کنند:
// Impure
const add = (a, b) => {
   Api.post('/add', { a, b }, (response) => {
    // Do something.
   });
};


روش‌هایی برای جلوگیری از تغییرات در اشیاء در جاوا اسکریپت

ایجاد تغییرات در آرایه‌ها و اشیاء (Mutating arrays and objects) نیز ناخالصی ایجاد می‌کند؛ از این جهت که سبب تغییراتی در دنیای خارج (خارج از میدان دید تابع) می‌شویم. به همین جهت نیاز به روش‌هایی وجود دارد که از این نوع تغییرات جلوگیری کرد:
// Copy object
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original);
برای تغییری در یک شیء، تنها کافی است خاصیتی را به آن اضافه کنیم و یا با استفاده از واژه‌ی کلیدی delete، خاصیتی را از آن حذف کنیم. به همین جهت برای اینکه تغییرات ما بر روی شیء اصلی اثری را باقی نگذارند، یکی از روش‌ها، استفاده از متد Object.assign است. کار آن، یکی کردن اشیایی است که به آن ارسال می‌شوند. به همین جهت در اینجا با یک شیء خالی، از صفر شروع می‌کنیم. سپس دومین آرگومان آن را به همان شیء مدنظر، تنظیم می‌کنیم. به این ترتیب به یک کپی از شیء اصلی می‌رسیم که دیگر به آن، اتصالی را ندارد. به همین جهت اگر بر روی این شیء کپی تغییراتی را ایجاد کنیم، به شیء اصلی کپی نمی‌شود و سبب تغییرات در آن (mutation) نخواهد شد.
برای مثال در React، برای انجام رندر نهایی، در پشت صحنه کار مقایسه‌ی اشیاء صورت می‌گیرد. به همین جهت اگر همان شیءای را که ردیابی می‌کند تغییر دهیم، دیگر نمی‌تواند به صورت مؤثری فقط قسمت‌های تغییر کرده‌ی آن‌را تشخیص داده و کار رندر را فقط بر اساس آن‌ها انجام دهد و مجبور خواهد شد کل یک شیء را بارها و بارها رندر کند که اصلا بهینه نیست. به همین جهت، ایجاد تغییرات مستقیم در شیءای که به state آن انتساب داده می‌شود، مجاز نیست.

متد Object.assign، چندین شیء را نیز می‌تواند با هم یکی کند و شیء جدیدی را تشکیل دهد:
// Extend object
const original = { a: 1, b: 2 };
const extension = { c: 3 };
const extended = Object.assign({}, original, extension);
روش دیگر ایجاد یک کپی و یا clone از یک شیء را که پیشتر در سری «React 16x» بررسی کردیم، به کمک امکانات ES-6، به صورت زیر است:
// Copy object
const original = { a: 1, b: 2 };
const copy = { ...original };
در اینجا نیز ابتدا یک شیء خالی را ایجاد می‌کنیم و سپس توسط spread operator، خواص شیء قبلی را درون آن باز کرده و قرار می‌دهیم. به این ترتیب به یک clone از شیء اصلی می‌رسیم. این حالت نیز از ترکیب چندین شیء با هم، پشتیبانی می‌کند:
// Extend object
const original = { a: 1, b: 2 };
const extension = { c: 3 };
const extended = { ...original, ...extension };


روش‌هایی برای جلوگیری از تغییرات در آرایه‌ها در جاوا اسکریپت

متد slice آرایه‌ها نیز بدون ذکر آرگومانی، یک کپی از آرایه‌ی اصلی را ایجاد می‌کند:
// Copy array
const original = [1, 2, 3];
const copy = [1, 2, 3].slice();
همچنین معادل همین قطعه کد در ES-6 به همراه spread operator به صورت زیر است:
// Copy array
const original = [1, 2, 3];
const copy = [ ...original ];
و یا اگر بخواهیم یک کپی از چندین آرایه را ایجاد کنیم می‌توان از متد concat استفاده کرد:
// Extend array
const original = [1, 2, 3];
const extended = original.concat(4);
const moreExtended = original.concat([4, 5]);
متد Array.push، هرچند سبب افزوده شدن عنصری به یک آرایه می‌شود، اما یک mutation را نیز ایجاد می‌کند؛ یعنی تغییرات آن به دنیای خارج اعمال می‌گردد. اما Array.concat یک آرایه‌ی کاملا جدید را ایجاد می‌کند و همچنین امکان ترکیب آرایه‌ها را نیز به همراه دارد.
معادل قطعه کد فوق در ES-6 و به همراه spread operator آن به صورت زیر است:
// Extend array
const original = [1, 2, 3];
const extended = [ ...original, 4 ];
const moreExtended = [ ...original, ...extended, 5 ];


مفاهیم ابتدایی Redux


در Redux برای ایجاد تغییرات در شیء کلی state، از مفهومی به نام dispatch actions استفاده می‌شود. action در اینجا به معنای رخ‌دادن چیزی است؛ مانند کلیک بر روی یک دکمه و یا دریافت اطلاعاتی از یک API. در این حالت مقایسه‌ای بین وضعیت قبلی state و وضعیت فعلی آن صورت می‌گیرد و تغییرات مورد نیاز جهت اعمال به UI، محاسبه خواهند شد.
اصلی‌ترین جزء Redux، تابعی است به نام Reducer. این تابع، یک تابع خالص است و دو آرگومان را دریافت می‌کند:


تابع Reducer، بر اساس action و یا رخ‌دادی، ابتدا کل state برنامه را دریافت می‌کند و سپس خروجی آن بر اساس منطق این تابع، یک state جدید خواهد بود. اکنون که این state جدید را داریم، برنامه‌ی React ما می‌تواند به تغییرات آن گوش فرا داده و بر اساس آن، UI را به روز رسانی کند. به این ترتیب کار اصلی مدیریت state، به خارج از برنامه‌ی React منتقل می‌شود.

در این تصویر، تابع action creator را هم ملاحظه می‌کند که کاملا اختیاری است. یک action می‌تواند یک رشته و یا یک عدد باشد. با پیچیده شدن برنامه، نیاز به ارسال یک‌سری متادیتا و یا اطلاعات بیشتری از اکشن رسیده‌است. کار action creator، ایجاد شیء action، به صورت یک دست و یکنواخت است تا دیگر نیازی به ایجاد دستی آن نباشد.


مزایای کار با Redux

- داشتن یک مکان مرکزی برای ذخیره سازی کلی حالت برنامه (به آن «source of truth» و یا store هم گفته می‌شود): به این ترتیب مشکل ارسال خواص در بین کامپوننت‌های عمیق و چند سطحی، برطرف شده و هر زمانیکه نیاز بود، از آن اطلاعاتی را دریافت و یا با قالب خاصی، آن‌را به روز رسانی می‌کنند.
- رسیدن به به‌روز رسانی‌های قابل پیش بینی state: هرچند در حالت کار با Redux، یک شیء بزرگ جاوا اسکریپتی، کل state برنامه را تشکیل می‌دهد، اما امکان کار مستقیم با آن و تغییرش وجود ندارد. به همین جهت است که برای کار با آن، باید رویدادی را از طریق actionها به تابع Reducer آن تحویل داد. چون Reducer یک تابع خالص است، با دریافت یک سری ورودی مشخص، همواره یک خروجی مشخص را نیز تولید می‌کند. به همین جهت قابلیت ضبط و تکرار را پیدا می‌کند؛ همان بحث serialize و deseriliaze، توسط ابزاری مانند: logrocket. به علاوه قابلیت undo و redo را نیز می‌توان به این ترتیب پیاده سازی کرد (state جدید محاسبه شده، مشخص است، کل state قبلی را نیز داریم یا می‌توان ذخیره کرد و سپس برای undo، آن‌را جایگزین state جدید نمود). افزونه‌ی redux dev tools نیز قابلیت import و export کل state را به همراه دارد.
- چون تابع Reducer، یک تابع خالص است و همواره خروجی‌های مشخصی را به ازای ورودی‌های مشخصی، تولید می‌کند، آزمایش کردن، پیاده سازی و حتی logging آن نیز ساده‌تر است. در این بین حتی یک افزونه‌ی مخصوص نیز برای دیباگ آن تهیه شده‌است: redux-devtools-extension. تابع خالص، تابعی است که به همراه اثرات جانبی نیست (side effects)؛ به همین جهت عملکرد آن کاملا قابل پیش بینی بوده و آزمون پذیری آن به دلیل نداشتن وابستگی‌های خارجی، بسیار بالا است.


Context API خود React چطور؟

در قسمت 33 سری React 16x، مفهوم React Context را بررسی کردیم. پس از معرفی آن با React 16.3، مقالات زیادی منتشر شدند که ... Redux مرده‌است (!) و یا بجای Redux از React context استفاده کنید. اما واقعیت این است که React Redux در پشت صحنه از React context استفاده می‌کند و تابع connect آن دقیقا به همین زیر ساخت متصل می‌شود.
کار با Redux مزایایی مانند کارآیی بالاتر، با کاهش رندر‌های مجدد کامپوننت‌ها، دیباگ ساده‌تر با افزونه‌های اختصاصی و همچنین سفارشی سازی، مانند نوشتن میان‌افزارها را به همراه دارد. اما شاید واقعا نیازی به تمام این امکانات را هم نداشته باشید؛ اگر هدف، صرفا انتقال ساده‌تر اطلاعات بوده و برنامه‌ی مدنظر نیز کوچک است. React Context برخلاف Redux، نگهدارنده‌ی state نیست و بیشتر هدفش محلی برای ذخیره سازی اطلاعات مورد استفاده‌ی در چندین و چند کامپوننت تو در تو است. هرچند شبیه به Redux می‌توان اشاره‌گرهایی از متدها را به استفاده کنندگان از آن ارسال کرد تا سبب بروز رویدادها و اکشن‌هایی در کامپوننت تامین کننده‌ی Contrext شوند (یا یک کتابخانه‌ی ابتدایی شبیه به Redux را توسط آن تهیه کرد). بنابراین برای انتخاب بین React Context و Redux باید به اندازه‌ی برنامه، تعداد نفرات تیم، آشنایی آن‌ها با مفاهیم Redux دقت داشت.
مطالب
اصول برنامه نویسی موازی درNET. نسخه 4 بخش اول - 2
تنظیم وضعیت برای یک Task  
در مثال ذکر شده در قسمت قبل هر چهار Task یک عبارت را در خروجی نمایش دادند حال می‌خواهیم هر Task پیغام متفاوتی را نمایش دهد.برای این کار از کلاس زیر استفاده می‌کنیم :  
System.Action<object>
تنظیم وضعیت برای یک Task این امکان را فراهم می‌کند که بر روی اطلاعات مختلفی یک پروسه مشابه را انجام داد.

مثال :  

namespace Listing_03 {
class Listing_03 {
  static void Main(string[] args) {
   // use an Action delegate and a named method
   Task task1 = new Task(new Action<object>(printMessage),"First task");

   // use an anonymous delegate
   Task task2 = new Task(delegate (object obj) {
     printMessage(obj);
   }, "Second Task");

   // use a lambda expression and a named method
   // note that parameters to a lambda don't need
   // to be quoted if there is only one parameter
   Task task3 = new Task((obj) => printMessage(obj), "Third task");

   // use a lambda expression and an anonymous method
   Task task4 = new Task((obj) => {
    printMessage(obj);
   }, "Fourth task");

  task1.Start();
  task2.Start();
  task3.Start();
  task4.Start();

  // wait for input before exiting
  Console.WriteLine("Main method complete. Press enter to finish.");
  Console.ReadLine();
}

 static void printMessage(object message) {
   Console.WriteLine("Message: {0}", message);
  }
 }
}
کد بالا را بروش دیگری هم می‌توان نوشت :  
using System;
using System.Threading.Tasks;

namespace Listing_04 {
class Listing_04 {
  static void Main(string[] args) {
   string[] messages = { "First task", "Second task",
    "Third task", "Fourth task" };

   foreach (string msg in messages) {
     Task myTask = new Task(obj => printMessage((string)obj), msg);
     myTask.Start();
  }

  // wait for input before exiting
  Console.WriteLine("Main method complete. Press enter to finish.");
  Console.ReadLine();
}

  static void printMessage(string message) {
   Console.WriteLine("Message: {0}", message);
  }
 }
}
نکته مهم در کد بالا تبدیل اطلاعات وضعیت Task به رشته کاراکتری است که در عبارت لامبدا مورد استفاده قرار می‌گیرد. System.Action فقط با داده نوع object کار می‌کند.
خروجی برنامه بالا بصورت زیر است :  
Main method complete. Press enter to finish.

Message: Second task

Message: Fourth task

Message: First task

Message: Third task
البته این خروجی برای شما ممکن است متفاوت باشد چون در سیستم شما ممکن است Task‌ها با ترتیب متفاوتی اجرا شوند.با کمک Task Scheduler برا حتی می‌توان ترتیب اجرای Task‌ها را کنترل نمود  

مطالب
کمی درباره دستورات using
شخصی سازی using directives
موقعی که یک کلاس جدید را در VS.NET باز میکنید، فضاهای نامی مشخص و تکراری، همیشه به صورت پیش فرض صدا زده شده‌اند و این فضاهای نام را مایکروسافت بر اساس بیشترین کاربرد و استفاده توسط برنامه نویسان قرار داده است؛ ولی در خیلی از اوقات این فضاهای نام پیش فرض، چنان هم برای خیلی از برنامه نویسان کاربردی نداشته یا با توجه به برنامه هایی که می‌نویسند همیشه متفاوت هست و هربار مجبورند فضاهای نام خاصی را صدا بزنند.
 برای مثال فضای نام System.ComponentModel.DataAnnotations را در نظر بگیرید که برنامه نویس میخواهد برای مدل‌های نوشته شده خود از تگ‌های متا استفاده کند و باید در هرکلاس ساخته شده، یکبار مورد بالا را صدا بزند که بیشتر باعث کند شدن کار برنامه نویس می‌شود. پس باید کاری کنیم که پیش فرض‌های فضای نام به آنچه خودمان میخواهیم تغییر پیدا کند.
برای این منظور، به محل نصب ویژوال استودیو رفته و مسیر زیر را دنبال کنید (به مسیر دقت کنید ،در اینجا زبان سی شارپ انتخاب شده است):
X:\...\IDE\ItemTemplates\CSharp\Code\1033
در اینجا تعدادی دایرکتوری با اسامی آشنا می‌بینید که داخل هر کدام از آن‌های یک فایل به اسم class.cs هست و اگر آن را باز کنید یک نمونه یا قالب برای using‌‌ها قابل مشاهده است. برای مثال ما وارد دایرکتوری class می‌شویم و فایل class.cs را باز می‌کنیم:
using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;
$endif$using System.Text;
$if$ ($targetframeworkversion$ >= 4.5)using System.Threading.Tasks;
$endif$
namespace $rootnamespace$
{
    class $safeitemrootname$
    {
    }
}
الان باید با یک نگاه به الگو، مشخص باشد که چکار باید بکنید.
یک سری از فضاهای نام که در تمامی فریمورک‌ها استفاده میشوند به همان شکل عادی نوشته شده‌اند. ولی آنهایی که از نسخه‌ی خاصی از یک فریم ورک اضافه شده‌اند باید توسط شرط مورد نظر اضافه شده و اعلام شود که این فضای نام از چه نسخه‌ی فریم ورکی به بعد باید اضافه گردد:
$if$ ($targetframeworkversion$ >= 3.5)using System.Linq;//فضای نام مورد نظر
$endif$
حالا تغییرات را ذخیره کنید و در VS.NET یک کلاس جدید را ایجاد کنید. همانطور که خواهید دید، تغییرات شما اعمال شده‌است. برای اعمال تغییرات نیازی به بستن و باز کردن مجدد VS.NET نمی‌باشد. در لحظه ایجاد کلاس الگو خوانده می‌شود.
حال در همان دایرکتوری سی شارپ دقت کنید، می‌بینید که برای موارد دیگری هم فایل هایی وجود دارند. برای مثال برای اینترفیس‌ها یا silverlight و ... که هر کدام را می‌توانید جداگانه تغییر دهید.
نکته:احتمال دارد در نسخه‌های متفاوت به خصوص پایین‌تر مثل نسخه 8 ویژوال استودیو ، فایل class.cs به صورت zip باشد که بعد از تغییرات باید دوباره به حالت zip بازگردانده شود.

حذف فضای نام‌های اضافی
هر موقع که کلاس جدیدی میسازیم، namespace‌ها به صورت پیش فرض که در بالا اشاره کردیم وجود دارند و شاید اصلا در آن کلاس از آن‌ها استفاده نمی‌کنیم یا حتی خودمان در حین نوشتن کدها چند namespace خاص را اضافه می‌کنیم که شاید در طول برنامه نویسی چندتایی را بلا استفاده بگذاریم. برای همین همیشه فضای نام هایی صدا زده شده‌اند که اصلا در آن کلاس استفاده نشده‌اند. پس برای همین بهتر هست که این رفرنس‌های بلا استفاده را پیدا کرده و آن‌ها را حذف کنیم.
شاید این سوال برای بعضی‌های پدید بیاد که چرا باید این‌ها را حذف کنیم، چون کاری هم با ما ندارند و ما هم کاری با آن‌ها نداریم؟
این کار چند علت میتواند داشته باشد:
  • تمیزکاری کد و خلوت شدن فضای کد‌نویسی
  • ممکن هست بعدها گیج کننده شود که من چرا از این‌ها استفاده کردم؟ در آینده با نگاه به یک کد تمیزتر متوجه میشوید یک کد از چه چیزهایی برای انجام کارش بهره‌مند شده و هم اینکه در کارهای گروهی و تیمی هم این مورد به شدت تاثیرگذار هست.
  • باعث کند شدن تحلیل‌های ایستا میشه (اینجا و اینجا )
  • کمپایل شدن کد کندتر میشه
  • موقع تست برنامه، اجرای اولیه کندتر خواهد بود چون CLR باید این نوع موارد را شناسایی و حذف کند
همه موارد بالا در مورد رفرنس‌های موجود یا همان dll‌های موجود در شاخه‌ی Bin و References هم صدق می‌کند.
برای حذف فضاهای نام اضافی در یک صفحه می‌توانید از طریق این مسیر انجام بدید:
Edit>IntelliSense >Organize Usings>Remove Unused using
برای مرتب سازی هم گزینه Sort Usings و انجام هر دو کار Remove and Sort موجود هست.
البته اگه روی صفحه هم راست کلیک کنید گزینه Organize Usings هم وجود دارد.
می توانید از ابزارهایی چون  Power tools Extensions هم استفاده کنید (در صورتی که ویژوال استودیوی شما گزینه‌های مورد نظر را ندارد، این ابزار را نصب نمایید) 
در صورتی که از ابزارهایی چون  telerik  یا  devexpress  استفاده می‌کنید یا از هر ابزار اضافی که بر روی IDE نصب می‌شود، عموما چنین گزینه هایی حتی با امکانات وسیعتر وجود دارند. مثلا  whole tomato  هم یکی از این ابزارهاست.
این نکته را هم خاطر نشان کنم در صورتیکه فضاهای نامی بین پیش پردازنده ها که در قبل توضیح دادیم محصور شده باشند، حذف نخواهند شد و همانطور باقی خواهند ماند.
در مورد کامنت‌های بین using‌ها به قطعه کد زیر نگاه کنید:
using System;
/* Comment before remains */
using /* Comment between removed */ System.Linq;
// Comment after remains
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("My Example");
}
}
}
و حالا بعد از حذف فضای نام‌های اضافی
using System;
/* Comment before remains */
// Comment after remains
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("My Example");
}
}
}
برای اینکه این عمل را بتونید در کل صفحات اعمال کنید می‌توانید از cleanup selected code هم استفاده کنید؛ به جز اینکه فضاهای نام اضافی را هم پاک می‌کند، کلیه کدهای شما را در قالبی شکیل‌تر و خواناتر قرار خواهد داد.
با کلید‌های Ctrl+k+d سند انتخابی و با کلیدهای ترکیبی Ctrl+k+f هم محدوده انتخاب شده قالب بندی می‌شود.
یکی دیگر از ابزارهایی که می‌توان با آن‌ها به کد سر و سامان بهتری داد، افزونه‌ی codemaid  هست.

ویژگی سی شارپ 6 در مورد Using
فرض کنید ما یک کلاس ایستا به نام utilities ایجاد کردیم که یک متد به اسم addints دارد. حالا و این کلاس در namespace به نام   SomeNamespace قرار دارد. مطمئنا در این حالت ما ابتدا فضای نام را using میکنیم و سپس در کد کلاس، متد را به شکل زیر صدا میزنیم:
using System;
using SomeNamespace;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int sum = Utility.AddInts(5, 2);
 
            Console.ReadLine();
        }
    }
}
ولی در سی شارپ 6 میتوانید بعد از فضای نام، یک . گذاشته و سپس اسم کلاس ایستا static را بیاورید و در کد مستقیما متد دلخواه خود را صدا بزنید.
به شکل زیر دقت کنید:
using System;
using SomeNamespace.Utility;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int sum = AddInts(5, 2);
 
            Console.ReadLine();
        }
    }
}
نکته پایانی:در visual studio 2014 فضاهای نام اضافی به رنگ خاکستری نمایش داده می‌شوند.

منابع:
اشتراک‌ها
کتابخانه qart.js

Generate artistic QR code  Demo

$ npm install qartjs

With React

This is a simple implementation of QArt as React Component. react-qart

With Angular.JS

There is a directive available for using qart.js in Angular.js: angular-qart

With Vue 2.x

There is a directive available for using qart.js in Vue.js 2.x : vue-qart 

کتابخانه qart.js
اشتراک‌ها
دات نت پایه، سی شارپ 8.0 و Nullable Reference Types

Here are some of the reasons why nullable reference types are less than ideal:

  • Invoking a member on a null value will issue a System.NullReferenceException exception, and every invocation that results in a System.NullReferenceException in production code is a bug. Unfortunately, however, with nullable reference types we “fall in” to doing the wrong thing rather than the right thing. The “fall in” action is to invoke a reference type without checking for null.
  • There’s an inconsistency between reference types and value types (following the introduction of Nullable<T>) in that value types are nullable when decorated with  “?” (for example, int? number); otherwise, they default to non-nullable. In contrast, reference types are nullable by default. This is “normal” to those of us who have been programming in C# for a long time, but if we could do it all over, we’d want the default for reference types to be non-nullable and the addition of a “?” to be an explicit way to allow nulls.
  • It’s not possible to run static flow analysis to check all paths regarding whether a value will be null before dereferencing it, or not. Consider, for example, if there were unmanaged code invocations, multi-threading, or null assignment/­replacement based on runtime conditions. (Not to mention whether analysis would include checking of all library APIs that are invoked.)
  • There’s no reasonable syntax to indicate that a reference type value of null is invalid for a particular declaration.
  • There’s no way to decorate parameters to not allow null. 
دات نت پایه، سی شارپ 8.0 و Nullable Reference Types
مطالب
سفارشی سازی صفحه‌ی اول برنامه‌های Angular CLI توسط ASP.NET Core
در مطلب «Angular CLI - قسمت پنجم - ساخت و توزیع برنامه» با نحوه‌ی ساخت و توزیع برنامه‌های Angular، در دو حالت محیط توسعه و محیط ارائه‌ی نهایی آشنا شدیم. همچنین در مطلب «یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017» نحوه‌ی ترکیب یک برنامه‌ی ASP.NET Core و Angular را بررسی کردیم. در اینجا می‌خواهیم فایل index.html ایی را که Angular CLI تولید می‌کند، با فایل Layout برنامه‌های ASP.NET Core جایگزین کنیم؛ تا بتوانیم در صورت نیاز، سفارشی سازی‌های بیشتری را به صفحه‌ی اول سایت اعمال نمائیم.


استفاده از Tag Helpers ویژه‌ی ASP.NET Core برای مدیریت محیط‌های توسعه و تولید

فایل‌های برنامه‌ی تک صفحه‌ای تولید شده‌ی توسط Angular CLI، در نهایت یک چنین شکلی را خواهند داشت:


این فایل‌ها نیز در حالت توسعه تهیه شده‌اند. در یک برنامه‌ی واقعی، صفحه‌ی ساده‌ی index.html تولیدی آن، تنها می‌تواند یک قالب شروع به کار باشد و نه فایل نهایی که قرار است ارائه شود. نیاز است به این فایل تگ‌های بیشتری را اضافه کرد و سفارشی سازی‌های خاصی را به آن اعمال نمود. در این حالت با توجه به بازنویسی و تولید مجدد این فایل در هر بار ساخت برنامه، می‌توان از فایل Layout پروژه‌ی ASP.NET Core جاری استفاده کرد. به این ترتیب از مزایای Razor و تمام زیرساختی که در اختیار داریم نیز محروم نخواهیم شد.
بنابراین تنها کاری را که باید انجام دهیم، کپی ساختار فایل index.html تولیدی به فایل Layout برنامه است.

مشکل! در حالت توسعه، نام فایل‌های تولید شده به همین سادگی است که ملاحظه می‌کنید. اما در حالت ارائه‌ی نهایی، این فایل‌ها به همراه یک هش نیز تولید می‌شوند (پیاده سازی مفهوم cache busting و اجبار به به‌روز رسانی کش مرورگر، باتوجه به تغییر آدرس فایل‌ها)؛ مانند vendor.ea3f8329096dbf5632af.bundle.js

راه حل اول: تولید فایل‌های نهایی بدون هش
 ng build -prod --output-hashing=none
در حین ساخت و تولید یک برنامه‌ی Angular CLI در حالت ارائه‌ی نهایی، تنها کافی است سوئیچ output-hashing، به none تنظیم شود، تا این هش‌ها به نام فایل‌های تولیدی اضافه نشوند.
درکل بهتر است از این روش استفاده نشود، چون با وجود پروکسی‌های کش کردن اطلاعات در بین راه، احتمال اینکه کاربران نگارش‌های قدیمی برنامه را مشاهده کنند، بسیار زیاد است.

راه حل دوم: تگ Script در ASP.NET Core اجازه‌ی ذکر تمام فایل‌های اسکریپت یک پوشه را نیز می‌دهد
 <script type="text/javascript" asp-src-include="*.js"></script>
هرچند این قابلیت جالب است و سبب الحاق یکجای تمام فایل‌های js موجود در پوشه‌ی wwwroot خواهد شد، اما پاسخگوی کار ما نخواهد بود؛ چون ترتیب قرارگیری این فایل‌ها مهم است.

راه حل واقعی
در اینجا کدهای کامل فایل Views\Shared\_Layout.cshtml را که می‌تواند جایگزین فایل index.html تولیدی توسط Angular CLI باشد، ملاحظه می‌کنید:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <title>ng2-lab</title>
    <base href="/">

    <environment names="Development">
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" asp-href-include="~/styles*.css" />
    </environment>
</head>
<body>
    @RenderBody()

<app-root></app-root>
<environment names="Development">
    <script type="text/javascript" src="/inline.bundle.js"></script>
    <script type="text/javascript" src="/polyfills.bundle.js"></script>
    <script type="text/javascript" src="/scripts.bundle.js"></script>
    <script type="text/javascript" src="/styles.bundle.js"></script>
    <script type="text/javascript" src="/vendor.bundle.js"></script>
    <script type="text/javascript" src="/main.bundle.js"></script>
</environment>
<environment names="Production,Staging">
    <script type="text/javascript" asp-src-include="~/inline*.js"></script>
    <script type="text/javascript" asp-src-include="~/polyfills*.js"></script>
    <script type="text/javascript" asp-src-include="~/scripts*.js"></script>
    <script type="text/javascript" asp-src-include="~/vendor*.js"></script>
    <script type="text/javascript" asp-src-include="~/main*.js"></script>
</environment>
</body>
</html>
در اینجا دو حالت توسعه و همچنین ارائه‌ی نهایی مدنظر قرار گرفته‌اند. در حالت توسعه، دقیقا از همان نام‌های ساده‌ی تولیدی استفاده شده‌است و در حالت ارائه‌ی نهایی چون نام فایل‌ها به صورت
[name].[hash].bundle.js
تولید می‌شوند، می‌توان قسمت هش را با * جایگزین کرد؛ مانند "asp-src-include="~/vendor*.js
همچنین باید دقت داشت که در حالت توسعه، تمام شیوه نامه‌های برنامه در فایل styles.bundle.js قرار می‌گیرند. اما در حالت ارائه‌ی نهایی، این فایل وجود نداشته و با نام کلی styles*.css تولید می‌شود که باید در head صفحه قرار گیرد (مانند تنظیمات حالت تولید در Layout فوق).


اصلاح قسمت URL Rewrite برنامه

در حالت کار با برنامه‌های تک صفحه‌ای وب، در اولین درخواست رسیده‌ی به برنامه ممکن است آدرسی درخواست شود که معادل کنترلر و اکشن متدی را در برنامه‌ی سمت سرور نداشته باشد. در این حالت کاربر را به همان صفحه‌ی index.html هدایت می‌کنیم تا سیستم مسیریابی سمت کلاینت، کار نمایش آن صفحه را انجام دهد:
app.Use(async (context, next) =>
{
    await next();
    var path = context.Request.Path.Value;
    if (path != null &&
        context.Response.StatusCode == 404 &&
        !Path.HasExtension(path) &&
        !path.StartsWith("/api/", StringComparison.OrdinalIgnoreCase))
        {
            context.Request.Path = "/index.html";
            await next();
        }
});
از آنجائیکه پس از اصلاحات فوق دیگر از این فایل استفاده نمی‌شود، باید تغییر ذیل را نیز اعمال کرد:
 //context.Request.Path = "/index.html";
context.Request.Path = "/"; // since we are using views/shared/_layout.cshtml now.


کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید.
نظرات مطالب
اعتبارسنجی مبتنی بر JWT در ASP.NET Core 2.0 بدون استفاده از سیستم Identity
- مقدار AccessTokenExpirationMinutes را در فایل تنظیمات برنامه تغییر دهید.
- مفهوم refresh token در اینجا شبیه به پیاده سازی sliding expiration برای کوکی‌ها است. اطلاعات بیشتر: «معرفی JSON Web Token» + مثال به روز رسانی خودکار توکن منقضی شده با یک تایمر سمت کلاینت، در سری «احراز هویت و اعتبارسنجی کاربران در برنامه‌های Angular» عمیق‌تر بررسی شده‌است. 
اشتراک‌ها
مقایسه چند فریم ورک AngularJs vs React vs Knockout vs Backbone vs Ember

Choosing the right framework for your projects is a daunting task and can affect the completion of the project in stipulated time period. Five widely used frameworks- AngularJSReactJsKnockoutBackbone and Ember give an option along with putting your knowledge to test to make a smart choice.  

مقایسه چند فریم ورک AngularJs vs React vs Knockout vs Backbone vs Ember