نظرات مطالب
آشنایی با NHibernate - قسمت هشتم
این مورد اصلا ربطی به using , try/catch و غیره ندارد. نیاز به solution کار شما است (با تمام کلاس‌ها و نگاشت و غیره) تا بتوان آن‌را دیباگ کرد. بهترین روش هم این است که خروجی SQL تولید شده را بررسی کنید تا متوجه شوید مشکل کار در کجاست.
اشتراک‌ها
استفاده از asp.net core web api، Razor page و mvc در یک پروژه .net core

اگر شما قبلا با asp.net core 2.0 به بالا کار کرده باشید هنگام ایجاد پروژه می‌دانید که از سه روش برای ایجاد پروژه وبی .net core می‌توان استفاده نمود. امکان استفاده جدا و با هم این روش‌ها وجود دارد که در این مقاله توضیحات کامل آن داده شده است.

استفاده از asp.net core web api، Razor page و mvc در یک پروژه .net core
مطالب
پیاده سازی پروژه‌های React با TypeScript - قسمت اول - معرفی و تعیین نوع props کامپوننت‌ها
React به صورت پیش‌فرض از ES6 برای توسعه‌ی برنامه‌‌های خودش استفاده می‌کند؛ اما استفاده‌ی از TypeScript با پروژه‌های React، مزایای قابل توجهی را مانند type checking در زمان کامپایل برنامه، دسترسی به intellisense آنی، امکان refactoring بهتر را در اختیار توسعه دهنده قرار می‌دهد که نه فقط سرعت و سهولت توسعه را افزایش می‌دهند، بلکه از بروز بسیاری از خطاهای زمان اجرای برنامه نیز جلوگیری می‌کند.


ایجاد پروژه‌های React مبتنی بر TypeScript

برای ایجاد ساختار ابتدایی پروژه‌های React که جهت استفاده‌ی از TypeScript تنظیم شده‌اند، دستور زیر را در خط فرمان اجرا می‌کنیم:
npx create-react-app tssample --template typescript
مزیت کار با npx، عدم نیاز به نصب محلی برنامه‌ی create-react-app است. به این ترتیب هربار که این دستور را به این نحو اجرا می‌کنیم، مطمئن خواهیم بود که از آخرین نگارش برنامه‌ی create-react-app استفاده خواهد شد؛ و نه نگارش محلی که پیشتر نصب کرده‌ایم که ممکن است هم اکنون تاریخ مصرف گذشته باشد.
بنابراین npx create-react-app کار اجرای آخرین نسخه‌ی برنامه‌ی ایجاد ساختار پروژه‌های React را انجام می‌دهد. پس از آن یک نام دلخواه ذکر شده‌است و در آخر توسط سوئیچ template typescript-- سبب خواهیم شد تا این ساختار بجای استفاده‌ی از ES6 پیش‌فرض، بر اساس TypeScript ایجاد و تنظیم شود.


بررسی ساختار پروژه‌ی TypeScript ای ایجاد شده


در تصویر فوق، نمونه‌ای از این ساختار ابتدایی ایجاد شده‌ی مبتنی بر TypeScript را مشاهده می‌کنید. اولین تفاوت مهم این ساختار، با ساختار پیش‌فرض پروژه‌های React مبتنی بر ES6، وجود فایل جدید tsconfig.json است. کار آن تنظیم پارامترهای کامپایلر TypeScript است. همچنین اینبار بجای پسوندهای js و jsx، پسوندهای ts و tsx قابل مشاهده هستند؛ مانند فایل‌های serviceWorker.ts ، index.tsx و App.tsx. البته اگر به ساختار این فایل‌ها دقت کنید، آنچنان تفاوت مهمی را با نمونه‌های قبلی ES6 خود ندارند و تقریبا یکی هستند. روش اجرای آن‌ها نیز مانند قبل است و با همان دستور npm start صورت می‌گیرد:



قابلیت استفاده‌ی از کدهای جاوا اسکریپتی موجود، در پروژه‌های تایپ اسکریپتی جدید

داخل پوشه‌ی src، پوشه‌ی جدید components را ایجاد کرده و داخل آن فایل جدید Head.js را اضافه می‌کنیم. سپس داخل آن rfac را نوشته و دکمه‌ی tab را فشار می‌دهیم تا ساختار ابتدایی یک react arrow functional component جدید ایجاد شود:
import React from "react";

export const Head = () => {
  return (
    <div>
      <h1>Hello</h1>
    </div>
  );
};
در ادامه جهت نمایش آن، آن‌را به فایل src\App.tsx به شکل متداولی، ابتدا با import تابع آن و سپس درج المان متناظر با آن در تابع App، اضافه می‌کنیم:
import { Head } from "./components/Head";
// ...

function App() {
  return (
    <div className="App">
      <Head />
      // ... 
    </div>
  );
}

export default App;
اگر دقت کرده باشید، پسوند این فایل را js درنظر گرفته‌ایم (src\components\Head.js) و نه ts و بدون مشکل می‌توان از آن در داخل یک فایل tsx استفاده کرد. علت آن به وجود تنظیم allowJs در فایل tsconfig.json برنامه بر می‌گردد. مزیت وجود یک چنین تنظیمی، امکان مهاجرت ساده‌تر کدهای ES6 موجود، به یک پروژه‌ی تایپ اسکریپتی جدید است. به این ترتیب می‌توان از تمام این کدها بدون مشکل در برنامه‌ی جدید خود استفاده کرد و سر فرصت، یکی یکی آن‌ها را به tsx تبدیل نمود.
به همین جهت پس از مشاهده‌ی این قابلیت، پسوند فایل کامپوننت جدید js ایجاد شده را به tsx تغییر می‌دهیم (src\components\Head.tsx). البته در یک چنین حالتی اگر هنوز دستور npm start در حال اجرا است، نیاز خواهید داشت یکبار آن‌را بسته و مجددا اجرا کنید. پس از آن، باز هم برنامه بدون مشکل کامپایل می‌شود و نشان دهنده‌ی این است که کدهای نوشته شده‌ی در کامپوننت Head، کدهای کاملا معتبر تایپ اسکریپتی نیز هستند. علت اینجا است که TypeScript، در حقیقت Superset جاوا اسکریپت به‌شمار می‌رود و قابلیت‌های جدیدی را به TypeScript استفاده می‌کند. بنابراین کدهای جاوااسکریپتی موجود، کدهای معتبر تایپ اسکریپتی نیز به‌شمار می‌روند.


مشخص کردن نوع props کامپوننت‌ها توسط TypeScript

اولین استفاده‌ی ما از TypeScript در اینجا، مشخص کردن نوع props یک کامپوننت است:
import React from "react";

export const Head = ({ title, isActive }) => {
  return (
    <div>
      <h1>{title}</h1>
      {isActive && <h3>Active</h3>}
    </div>
  );
};
برای این منظور، دو خاصیت جدید را از طریق شیء props به این کامپوننت ارسال کرده و از آن‌ها جهت نمایش یک عنوان و تعیین نمایش یک برچسب استفاده می‌کنیم. اولین موردی را که پس از این تغییر متداول مشاهده می‌کنیم، خط قرمز کشیده شدن زیر متغیرهای حاصل از Object Destructuring مربوط به شیء props است:


علت اینجا است که این فایل، tsx است و نه js. به همین جهت نوع این متغیرها را، همان حالت پیش‌فرض جاوا اسکریپت که any است، درنظر گرفته‌است و ... این مورد بر اساس تنظیمات فایل tsconfig.json برنامه، ممنوع است. البته اگر به این فایل دقت کنید، شاید چنین گزینه‌ای را به صورت صریح نتوانید در آن پیدا کنید. علت اینجا است که تعداد گزینه‌های قابل تنظیم در فایل tsconfig روز به روز بیشتر می‌شوند. به همین جهت برای ساده سازی فعالسازی آن‌ها، از TypeScript 2.3 به بعد، پرچم strict نیز به این تنظیمات اضافه شده‌است. کار آن فعالسازی یکجای تمام بررسی‌های strict است؛ مانند noImplicitAny، strictNullChecks و غیره.
{ 
    "compilerOptions": { 
        "strict": true  /* Enable all strict type-checking options. */ 
    } 
}
در این حالت اگر نیاز به لغو یکی از گزینه‌ها بود، می‌توان به صورت ذیل عمل کرد:
{ 
    "compilerOptions": { 
        "strict": true, 
        "noImplicitAny": false 
    } 
}
گزینه‌ی strict تمام بررسی‌های متداول را فعال می‌کند؛ اما ذکر و تنظیم صریح noImplicitAny به false، تنها این یک مورد را لغو خواهد کرد.
بنابراین چون در فایل tsconfig.json برنامه‌ی React ما گزینه‌ی strict به true تنظیم شده‌است، گزینه‌ی فعال noImplicitAny نیز جزئی از آن است و دیگر نمی‌توان متغیر یا خاصیتی را بدون ذکر صریح نوع آن، رها کرد.

برای رفع خطای noImplicitAny موجود، به ابتدای فایل src\components\Head.tsx، نوع جدید Props را اضافه می‌کنیم (نام آن کاملا دلخواه است):
type Props = {
  title: string;
  isActive: boolean;
};
و سپس از آن جهت مشخص سازی نوع شیء props رسیده، به نحو زیر استفاده خواهیم کرد:
export const Head = ({ title, isActive }: Props) => {
پس از این تغییر، خطای noImplicitAny پیشین، برطرف می‌شود و دیگر خطوط قرمز ذیل دو متغیر حاصل از Object Destructuring، مشاهده نمی‌شوند.

یک نکته: البته اگر از سری React 16x بخاطر داشته باشید، می‌توان یک چنین قابلیتی را توسط propTypes خود React نیز پیاده سازی کرد:
Head.propTypes = {
  title: PropTypes.string,
  isActive: PropTypes.bool
}
 اما روش کار با TypeScript، نسبت به آن بسیار پیشرفته‌تر است. برای کار با TypeScript، نیازی به import یک بسته‌ی جدید، مانند PropTypes نیست و همچنین بررسی PropTypes توسط خود React، در زمان اجرای برنامه صورت می‌گیرد؛ اما با TypeScript، بررسی زمان کامپایل برنامه را خواهیم داشت و همچنین نمایش آنی خطاهای مرتبط با عدم رعایت آن‌ها، در ادیتورهایی مانند VSCode. به علاوه روش تعریف type ذکر شده‌ی توسط TypeScript، نسبت به نمونه‌ی پیشنهاد شده‌ی توسط React با propTypes، بسیار تمیزتر و خواناتر است.

پس از این تغییر، اگر به فایل src\App.tsx مراجعه کنیم، مشاهده می‌کنیم که ذیل تعریف المان کامپوننت Head، مجددا خط قرمزی کشیده شده‌است:


عنوان می‌کند که بر اساس نوع جدید Props ای که تعریف کرده‌اید، نیاز است دو خاصیت اجباری title و isActive را نیز در اینجا ذکر کنید؛ وگرنه تعریف این المان، بدون آن‌ها ناقص است.
امکان جالب دیگری که با تعریف نوع props توسط تایپ‌اسکریپت رخ می‌دهد، فعال شدن intellisense متناظر با تعریف این خواص و ویژگی‌ها است:


در ادامه با تعریف این دو ویژگی جدید، خط قرمز رنگ ذیل کامپوننت Head برطرف می‌شود:
<Head title="Hello" isActive={true} />
و اگر در حین تعریف این ویژگی‌ها، نوع‌های مقادیر آن‌ها را به درستی وارد نکنیم، بازهم شاهد تذکر آنی خطاهای مرتبط با آن‌ها خواهیم بود:


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

بنابراین به صورت خلاصه مزیت‌های کار با TypeScript برای تعاریف نوع props به شرح زیر است:
- auto-complete و داشتن intellisense خودکار.
- اگر نام المان کامپوننتی و یا نام یکی از props را به اشتباه وارد کنیم، بلافاصله خطای یافت نشدن آن‌ها را نمایش می‌دهد.
- اگر ذکر یک prop اجباری را فراموش کنیم، بلافاصله خطای متناظری را دریافت می‌کنیم.
- اگر نوع مقدار یکی از props را به اشتباه وارد کنیم، باز هم خطایی را جهت گوشزد کردن آن مشاهده خواهیم کرد.
- فعال بودن TypeScript، امکان refactoring بسیار قوی‌تری را میسر می‌کند. برای مثال با فشردن دکمه‌ی F2 می‌توان نام یک کامپوننت را در کل برنامه به سادگی تغییر داد. همچنین یک چنین قابلیتی برای تغییر نام props نیز میسر است و به صورت خودکار تمام کاربردهای آن‌را نیز به روز می‌کند.
- اگر نوع prop ای را در تعریف آن تغییر دادیم، اما مقدار منتسب به آن‌را خیر، باز هم بلافاصله متوجه این مشکل خواهیم شد.

به این ترتیب با دسترسی به بررسی‌های دقیق زمان کامپایل برنامه، می‌توان مشکلات بسیار کمتری را در زمان اجرای آن شاهد بود.
نظرات مطالب
یافتن خطاهای متداول کدهای جاوا اسکریپتی با غنی سازی تنظیمات کامپایلر TypeScript
یک نکته‌ی تکمیلی: ساده سازی فعالسازی گزینه‌های مختلف کامپایلر TypeScript

پس از به روز رسانی کامپایلر تایپ‌اسکریپت با دستور npm install -g typescript، اگر دستور tsc --init را در یک پوشه‌ی جدید اجرا کنید، سبب تولید یک فایل tsconfig.json از پیش تنظیم شده، بر اساس آخرین قابلیت‌های کامپایلر TypeScript می‌شود. برای مثال تنظیمات ذیل قسمتی از تنظیمات نگارش 2.7.1 است و برای نمونه strictPropertyInitialization به آن اضافه شده‌است:
    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
اگر می‌خواهید به ازای هر به روز رسانی کامپایلر تایپ‌اسکریپت این تنظیمات را تغییر ندهید، فقط کافی است تنظیم strict": true" را قید کنید و مابقی را تنها در صورت نیاز به false کردن آن‌ها ذکر نمائید.
اشتراک‌ها
تحقق یک رویا: پشتیبانی توکار از دات نت در همه مرورگرهای مدرن

به لطف استاندارد مدرن و هنوز فراگیر نشده‌ی WebAssembly ، امروزه همه‌ی مرورگر‌های مدرن می‌توانند بجای اجرای جاوا اسکریپت، یک زبان bytecode استانداردِ سطح پایین و شبیه به زبان اسمبلی را اجرا کنند. استفاده از WebAssembly می‌تواند موجب اجرای سریع‌تر کد و کاهش حجم آن شود. اما مهمترین مزیت این هست که امروز می‌توانیم همه‌ی زبان‌های قدرتمند، نظیر سی شارپ را به نحوی کامپایل کنیم که خروجیِ نهایی، منطبق با استاندارد webassembly باشد و به صورت native در مرورگرها، دات نت را اجرا کنیم.

کامپایل سی شارپ به WebAssembly توسط تیم Mono مایکروسافت انجام شده و عمده مشکلات فنی سر راه برداشته شده‌اند. اما برای اینکه عملا بشود از دات نت در مرورگر‌ها استفاده کرد، مایکروسافت در پی پیاده سازی پروژه‌ی جاه طلبانه‌ای به نام Blazor می‌باشد. در واقع Blazor فریم ورک Client-Side مبتنی بر دات نت خواهد بود؛ الهام گرفته از فریم ورک‌های کنونی (مانند Angular و React) و رقیبی جدید برای آن‌ها. فریم ورک Blazor هم مانند آن‌ها حول مفهوم Component شکل گرفته‌است. کامپوننت‌هایی که کلاس‌های سی شارپی هستند و با زبان Razor توسعه داده شده‌اند. 

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

همچنین با استفاده از WebAssembly می‌توانیم به تمام کتابخانه‌های موجود جاوااسکریپتی هم دسترسی داشته باشیم و محدودیتی در این زمینه وجود ندارد. همچنین می‌توان DOM را هم از این طریق مدیریت و دستکاری کرد.

در حال حاضر تیم AspNet عهده دار کار بر روی پروژه‌ی Blazor  شده‌است. از نوشته‌های آن‌ها چنین بر می‌آید که تا نهایی شدن این پروژه هنوز باید صبر کنیم.  

تحقق یک رویا: پشتیبانی توکار از دات نت در همه مرورگرهای مدرن
نظرات مطالب
بررسی روش آپلود فایل‌ها از طریق یک برنامه‌ی Angular به یک برنامه‌ی ASP.NET Core
یک نکته‌ی تکمیلی
به همراه نگارش Angular 4.3، روش جدیدی برای کار با HTTP، توسط ماژول جدید HTTP Client آن ارائه شده‌است که ساختار آن بسیار شبیه به ماژول فعلی HTTP آن است و کدهای فعلی را به سادگی می‌توان به آن انتقال داد. یکی از تغییرات آن داشتن رخ‌دادهای درصد آپلود و دانلود یک درخواست است:
import {  HttpEventType,  HttpClient,  HttpRequest } from '@angular/common/http';

http.request(new HttpRequest(
  'POST',
  URL,
  body, 
  {
    reportProgress: true
  })).subscribe(event => {
  if (event.type === HttpEventType.DownloadProgress) {
  }

  if (event.type === HttpEventType.UploadProgress) {
  }

  if (event.type === HttpEventType.Response) {
    console.log(event.body);
  }
})
به این ترتیب بدون نیاز به کامپوننت اضافه‌تری می‌توان درصد پیشرفت آپلود را نمایش داد.

برای مطالعه‌ی بیشتر:
The Angular HTTP Client - Quickstart Guide 
A Taste From The New Angular HTTP Client  
نظرات مطالب
راه‌اندازی Http Interceptor در Angular
یک نکته‌ی تکمیلی
به همراه نگارش Angular 4.3، روش جدیدی برای کار با HTTP، توسط ماژول جدید HTTP Client آن ارائه شده‌است که ساختار آن بسیار شبیه به ماژول فعلی HTTP آن است و کدهای فعلی را به سادگی می‌توان به آن انتقال داد. یکی از تغییرات آن داشتن HttpInterceptor به صورت توکار است:
import { HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';

@Injectable()
class JWTInterceptor implements HttpInterceptor {
    constructor(private userService: UserService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          const JWT = `Bearer ${this.userService.getToken()}`;
          req = req.clone({
                     setHeaders: {
                        Authorization: JWT
                     }
                });
          return next.handle(req);
    }
}

برای مطالعه‌ی بیشتر:
The Angular HTTP Client - Quickstart Guide 
A Taste From The New Angular HTTP Client 
مطالب
AngularJS #1
پیش از اینکه آموزش AngularJs را شروع کنیم بهتر است با مفهوم برنامه‌های تک صفحه ای وب  و یا  Single Page Web Applications آشنا شویم؛ چرا که AngularJS برای توسعه هر چه ساده‌تر و قوی‌تر این گونه برنامه‌ها متولد شده است.

Single Page Application
برای درک چگونگی کارکرد این برنامه ها، مثالی را میزنیم که هر روزه با آن سرو کار دارید، یکی از نمونه‌های کامل و قدرتمند برنامه‌های Single Page Application و یا به اختصار SPA، سرویس پست الکترونیکی Google و یا همان Gmail است.
اجازه بدهید تا ویژگی‌های SPA را با بررسی Gmail انجام دهم، تا به درک روشنی از آن برسید:

Reload نشدن صفحات
در Gmail هیچ گاه صفحه Reload و یا اصطلاحا بارگیری مجدد نمی‌شود. برای مثال، وقتی شما لیست ایمیل‌های خود را مشاهده میکنید و سپس بر روی یکی از آن‌ها کلیک میکنید، بدون اینکه به صفحه ای دیگر هدایت شوید؛ایمیل مورد نظر را میبینید. در حقیقت تمامی اطلاعات در همان صفحه نمایش داده می‌شوند و بر عکس وب سایت‌های معمول است که از صفحه ای به صفحه‌ی دیگر هدایت میشوید ، در یک صفحه تمام کارهای مورد نیاز خود را انجام می‌دهید و احتیاجی به بارگیری مجدد صفحات نیست. با توجه به این صحبت‌ها برای توسعه دهنده‌های وب آشکار است که تکنیک AJAX، نقشی اساسی در این گونه برنامه‌ها دارد، چون کلیه‌ی عملیات ارتباط با سرور در پشت زمینه انجام می‌شوند.

تغییر URL در نوار آدرس مرورگر
وقتی شما بر روی یک ایمیل کلیک می‌کنید و آن ایمیل را بدون Reload شدن مجدد صفحه مشاهده می‌کنید، آدرس صفحه در مرورگر نیز تغییر می‌کند. خب مزیت این ویژگی چیست؟ مزیت این ویژگی در این است که هر ایمیل شما دارای یک آدرس منحصر به فرد است و به شما امکان Bookmark کردن آن لینک، باز کردن آن در یک Tab جدید و یا حتی ارسال آن به دوستان خود را دارید. حتی اگر این مطلب را جدا از Gmail در نظر بگیریم، به موتور‌های جست و جو کمک می‌کند، تا هر صفحه را جداگانه Index کنند؛ جدا از اینکه وبسایت ما SPA است. همچنین این کار یک مزیت مهم دیگر نیز دارد؛ و آن کار کردن کلیدهای back و forward مرورگر، برای بازگشت به صفحات پیمایش شده قبلی است.
شاید قبل از بیان این ویژگی با خود گفته باشید که پیاده سازی Reload نشدن صفحات با AJAX آن چنان کار پیچیده ای نیست. بله درست است، اما آیا شما قبل از این راه حلی برای تغییر URL اندیشیده بودید؟ مطمئنا شما هم صفحات وب زیادی را دیده اید که همه‌ی صفحات آن دارای یک URL در نوار آدرس مرورگر هستند و هیچگاه تغییر نمی‌کنند و با باز کردن یک لینک در یک Tab جدید، باز همان صفحه‌ی تکراری را مشاهده می‌کنند! و یا بدتر از همه که دکمه‌ی back مرورگر غیر عادی عمل می‌کند. بله، اینها تنها تعدادی از صدها مشکلات رایج سیستم‌های نوشته شده ای است که سعی کردند همه‌ی کارها در یک صفحه انجام شود.

Cache شدن اطلاعات دریافتی
شاید خیلی‌ها ویژگی‌های فوق را برای یک SPA کافی بدانند، اما تعدادی هم مانند نگارنده وجود یک کمبود را حس می‌کنند و آن کش شدن اطلاعات دریافتی در مرورگر است. Gmail این امکان را به خوبی پیاده سازی کرده است. لیست ایمیل‌های دریافتی در بار اول از سرور دریافت می‌شود، سپس شما بر روی یک ایمیل کلیک و آن را مشاهده می‌کنید. حال به لیست ایمیل‌های دریافتی بازگردید، آیا رفت و برگشتی به سرور انجام می‌شود؟ مسلما خیر. حتی اگر دوباره بر روی آن ایمیل مشاهده شده ، کلیک کنید، بدون رفت و برگشتی به سرور آن ایمیل را مشاهده می‌کنید.
کش شدن اطلاعات سبب می‌شود که بار سرور خیلی کاهش یابد و رفت و آمدهای بیهوده صورت نگیرد. کش شدن داده‌ها یک مزیت دیگر نیز دارد و آن تبدیل برنامه‌های معمول وب stateless به برنامه‌های شبه دسکتاپ state full است. 
  
تکنیک AJAX در پیاده سازی امکانات فوق نقشی اساسی را بازی می‌کند. کمی به عقب برمیگردیم یعنی زمانی که AJAX برای اولین بار مطرح شد و هدف اصلی به وجود آمدن آن پیاده سازی برنامه‌های وب به شکل دسکتاپ بود و این کار از طریق انجام تمامی ارتباطات سرور با  XMLHttpRequest  امکان پذیر می‌شد. شاید آن زمان با توجه به محدودیت تکنولوژی‌ها موجود این کار به صورت تمام و کمال امکان پذیر نبود، اما امروزه به بهترین شکل ممکن قابل پیاده سازی است.

 شاید اکنون این سوال پیش بیاید که چرا باید وبسایت خود را به شکل SPA طراحی کنیم؟
برای پاسخ دادن به این سوال باید گفت که سیستم‌های وب  امروزی به دو دسته‌ی زیر تقسیم می‌شوند:
Web Documents و یا همان وب سایت‌های معمول
Web Applications و یا همان Single Page Web Applications
اگر هدف شما طراحی یک وب سایت معمول است که هدف آن، نمایش یک سری اطلاعات است و به قولی دارای محتواست، مطمئنا پیاده سازی این سیستم به صورت SPA کاری بیهوده به نظر می‌آید؛ ولی اگر هدفتان نوشتن سیستم هایی مثل Gmail، Google Maps، Azure، Facebook و ... است، پیاده سازی آن‌ها به صورت وب سایت‌های معمولی، غیر معقول به نظر می‌آید. حتی بخش‌های مدیریتی یک وبسایت هم می‌تواند به خوبی توسط SPA پیاده سازی شود، چرا که واقعا برای مدیریت اطلاعات یک وب سایت احتیاجی نیست، که  از این صفحه به آن صفحه جا به جا شد.

معرفی کتابخانه‌ی AngularJS
AngularJS فریم ورکی متن باز و نوشته شده به زبان جاوا اسکریپت است. هدف از به وجود آمدن این فریم ورک، توسعه هر چه ساده‌تر SPA‌ها با الگوی طراحی MVC و تست پذیری هر چه آسان‌تر آن‌ها است. این فریم ورک توسط یکی از محققان Google در سال 2009 به وجود آمد. بعد‌ها این فریم ورک تحت مجوز MIT به صورت متن باز در آمد و اکنون گوگل آن را حمایت می‌کند و توسط هزاران توسعه دهنده در سرتاسر دنیا، توسعه داده می‌شود.
قبل از اینکه به بررسی ویژگی‌های Angular بپردازم، بهتر است ابتدا مطلبی درباره‌ی به کارگیری Angular از Brad Green که کارمند گوگل است، بیان کنم.
در سال 2009 تیمی در گوگل مشغول انجام پروژه ای به نام Google Feedback بودند. آن‌ها سعی داشتند تا در طی چند ماه، به سرعت کد‌های خوب و تست پذیر بنویسند. پس از 6 ماه کدنویسی، نتیجه‌ی کار 17000 خط کد شد. در آن موقع یکی از اعضای تیم به نام Misko Hevery، ادعا کرد که می‌تواند کل این پروژه را در دو هفته به کمک کتابخانه‌ی متن بازی که در اوقات فراغت توسعه داده است، بازنویسی کند. Misko نتوانست در دو هفته این کار را انجام دهد. اما پس از سه هفته همه‌ی اعضای تیم را شگفت زده کرد. نتیجه‌ی کار تنها 1500 خط بود! همین باعث شد که ما بفهمیم که، Misko بر روی چیزی کاری میکند که ارزش دنبال کردن دارد.
پس از آن قضیه Misko و Brad بر روی Angular کار کردند و اکنون هم Angular توسط تیمی در گوگل و هزاران توسعه دهنده‌ی متن باز حرفه ای در سرتاسر جهان، درحال توسعه است.
فکر کنم همین داستان ذکر شده، قدرت فوق العاده زیاد این فریم ورک را برای همگان آشکار سازد.

ویژگی‌های AngularJS:

قالب‌های سمت کاربر (Client Side Templates): انگولار دارای یک template engine قدرتمند برای تعریف قالب است.

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

Data Binding: امکان تعریف انقیاد داده دوطرفه (Two-Way Data Binding) در این فریم ورک به راحتی هرچه تمام، امکان پذیر است.

Dependency Injection: این فریم ورک برای دریافت وابستگی‌های تعریف شده، دارای یک سیستم تزریق وابستگی توکار است.

تعریف Service‌های سفارشی: در این فریم ورک امکان تعریف سرویس‌های دلخواه به صورت ماژول وجود دارد. این ماژول‌های مجزا را به کمک سیستم تزریق وابستگی توکار Angular، به راحتی در هر جای برنامه می‌توان تزریق کرد.

تعریف Directive‌های سفارشی: یکی از جذاب‌ترین و قدرتمند‌ترین امکانات این فریم ورک، تعریف Directive‌های سفارشی است.  Directive ها، امکان توسعه HTML را فراهم کرده اند. توسعه‌ی HTML اکنون در قالب Web Components‌ها فراهم شده است، اما هنوز هم خیلی از مرورگر‌های جدید نیز از آن پشتیبانی نمی‌کنند.

فرمت کردن اطلاعات با استفاده از فیلترهای سفارشی: با استفاده از فیلترها میتوانید چگونگی الحاق شدن اطلاعات را برای نمایش به کاربر تایین کنید ؛ انگولار همراه با فیلترهای گوناگون مختلفی عرضه میشود که میتوان برایه مثال به فیلتر currency ، date ،uppercase کردن رشته‌ها و .... اشاره کرد همچنین شما محدود به فیلترهای تعریف شده در انگولار نیستید و آزادید که فیلترهای سفارشی خودتان را نیز تعریف کنید.

سیستم Routing: دارا بودن سیستم Routing  قدرتمند، توسعه SPA‌ها را بسیار ساده کرده است.

سیستم اعتبار سنجی: Angular دارای سیستم اعتبار سنجی توکار قدرتمند برای بررسی داده‌های ورودی است.

سرویس تو کار برای ارتباط با سرور: Angular دارای سرویس پیش فرض ارتباط با سرور به صورت AJAX است.

تست پذیری: Angular دارای بستری آماده برای تست کردن برنامه‌های نوشته شده است و از Unit Tests و Integrated End-to-End Test هم پشتیبانی می‌کند.

جامعه‌ی متن باز بسیار قوی
   
این‌ها فقط یک مرور کلی بر توانایی‌های این فریم ورک بود و در ادامه هر کدام از این ویژگی را به صورت دقیق بررسی خواهیم کرد.
در مقاله‌ی بعدی، به چگونگی نصب AngularJS خواهیم پرداخت. سپس، اولین کد خود را با استفاده از آن خواهیم نوشت و مطالب Client Side Templates و MVC را دقیق‌تر بررسی خواهیم کرد.
 
مطالب
مبانی TypeScript؛ متغیرها و نوع‌ها
روش‌های مختلف تعریف متغیرها در TypeScript

تمام توسعه دهنده‌های JavaScript با واژه‌ی کلیدی var آشنایی دارند؛ اما TypeScript واژه‌های کلیدی let و const را نیز اضافه کرده‌است (که جزئی از ES 6 نیز می‌باشند). تفاوت مهم بین var و let، در میدان دید متغیرهای تعریف شده‌ی توسط آن‌ها خلاصه می‌شود. پیشتر در سری مباحث بررسی ES 6، مطلب «متغیرها در ES 6» را نیز بررسی کردیم که در TypeScript نیز صادق می‌باشند؛ با این تفاوت که TypeScript را می‌توان به ES 5 نیز کامپایل کرد و بدون مشکل با تمام مرورگرهای موجود، اجرا نمود.
- متغیرهایی که با var تعریف می‌شوند، به صورت سراسری در متدی که تعریف شده‌اند، قابل دسترسی هستند؛ حتی اگر 5 سطح داخل ifهای تو در تو تعریف شده باشند. اما let و const تنها در block و قطعه‌ای که معرفی شده‌اند، معتبر بوده و خارج از آن تعریف نشده‌اند. در اینجا یک block توسط {} معرفی می‌شود.
- متغیرهای از نوع var به دلیل مفهومی به نام hoisting توسط runtime جاوا اسکریپت، به بالاترین سطح متد منتقل می‌شوند. به همین دلیل عمق تعریف آن‌ها، اثری در دسترسی به این متغیرها ندارد. اما hoisting در مورد let و const اعمال نمی‌شود.
- متغیرهای var را می‌توان چندبار مجددا تعریف کرد (هرچند این روش توصیه نمی‌شود؛ اما مجاز است). یک چنین تعریف مجددی با متغیرهای از نوع let و const مجاز نیست.
برای توضیحات بیشتر به مثال ذیل دقت کنید:
function ScopeTest() {
    if (true) {
        var foo = 'use anywhere';
        let bar = 'use in this block';
    }
    console.log(foo); // works!
    console.log(bar); // error!
}
در اینجا داخل قطعه‌ی if تعریف شده، یک متغیر، از نوع var و متغیر دیگری از نوع let تعریف شده‌است. خارج از بدنه‌ی این متد، متغیر foo هنوز قابل دسترسی است، اما متغیر bar خیر.


نوع‌های پایه‌ی TypeScript

نوع‌های پایه‌ی TypeScript شامل موارد ذیل هستند:
Boolean: برای ذخیره سازی true یا false.
let isDone: boolean = false;
Number: معرف مقادیر عددی اعشاری هستند.
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
String: مقادیر رشته‌ای را ذخیره می‌کند.
let name: string = "bob";
name = 'smith';
Array: روش‌های متفاوتی برای تعریف آرایه‌ها در TypeScript وجود دارند که در ادامه آن‌ها را بیشتر بررسی خواهیم کرد.
let list: number[] = [1, 2, 3];
Enum: نوع‌های شمارشی؛ جهت دادن نام‌هایی بهتر به مجموعه‌ی مشخصی از مقادیر.
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
Any: به این معنا که یک متغیر می‌تواند به هر نوع دلخواهی اشاره کند. هدف از وجود این نوع، امکان استفاده‌ی از کتابخانه‌های فعلی جاوا اسکریپتی است که نوعی برای متغیرهای آن‌ها تعریف نشده‌اند و در اساس هر نوعی می‌توانند باشند. برای مثال در جاوا اسکریپت مجاز است در سطر اول متغیری را تعریف کرد و در سطر دوم به آن یک رشته و در سطر سوم به آن یک عدد را انتساب داد.
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
Void: به معنای فقدان یک نوع است. برای مثال مشخص کردن اینکه متدی، خروجی ندارد.
 function warnUser(): void {
        alert("This is my warning message");
}

یک نکته: قابلیت Template string در ES 6 نیز در TypeScript پشتیبانی می‌شود.



مفهوم Type Inference در TypeScript

در TypeScript الزاما نیازی نیست تا نوع متغیری را صریحا مشخص کرد. در اینجا اگر نوع متغیری را در ابتدای کار تعریف نکنید، نوع آن در اولین باری که مقدار دهی می‌شود، مشخص خواهد شد که به آن Type Inference نیز می‌گویند.
let myString= 'this is a string';
myString= 42; // error!
در مثال فوق، نوع متغیر myString در زمان تعریف آن مشخص نشده‌است؛ اما با یک رشته، مقدار دهی و آغاز شده‌است. بر این اساس، TypeScript نوع این متغیر را رشته‌ای در نظر می‌گیرد و در سطر بعدی، از انتساب یک مقدار عددی به آن جلوگیری خواهد کرد.
و یا در مثال ذیل، نوع خروجی متد ReturnNumber به صورت صریح مشخص نشده‌است:
function ReturnNumber() {
   return 42;
}
let anotherString = 'this is also a string';
anotherString = ReturnNumber(); // error!
اما با توجه به اینکه خروجی آن عددی است، نوع آن نیز عددی درنظر گرفته شده و از انتساب آن به یک متغیر رشته‌ای جلوگیری می‌شود.


تعریف صریح نوع‌ها در TypeScript با استفاده از Type Annotations

برای لغو Type Inference و تعیین صریح نوع‌ها در TypeScript می‌توان به صورت زیر عمل کرد:
let myString : string = 'this is a string';
myString = 42; // error!

function ReturnNumber() : number {
   return 42;
}
let anotherString : string = 'this is also a string';
anotherString = ReturnNumber(); // error!
با قراردادن یک کولن پس از نام متغیر و سپس تعریف نوع داده‌ی مدنظر، می‌توان نوع‌ها را در TypeScript به صورت صریحی تعریف کرد. در مورد متدها نیز به همین صورت است. کولن پس از پایان بسته شدن پرانترها قرار می‌گیرد و سپس نوع بازگشتی متد مشخص می‌گردد.


نوع‌های شمارشی در TypeScript

Enums در بسیاری از زبان‌های برنامه نویسی متداول وجود دارند و هدف از آن‌ها، دادن نام‌هایی بهتر و مشخص، به مجموعه‌ای از مقادیر است:
 enum Category { Biography, Poetry, Fiction }; // 0, 1, 2
در مثال فوق یک enum جهت تعریف گروه‌های کتاب‌ها تعریف شده‌است. در اینجا بجای استفاده از مقادیر نامفهوم 0 تا 2، نام‌هایی مشخص و بهتر، جهت معرفی آن‌ها ارائه شده‌اند. به این ترتیب می‌توان در نهایت به کدهایی خواناتر رسید.
اگر می‌خواهید این مقادیر با اعداد دیگری شروع شوند (بجای صفر پیش فرض)، می‌توان مقدار اولین نام را به صورت صریحی مشخص کرد:
 enum Category { Biography = 1, Poetry, Fiction }; // 1, 2, 3
و یا الزامی به استفاده از مقادیر افزایش یابنده‌ای در اینجا نیست. در صورت نیاز می‌توان مقدار هر المان را جداگانه تعریف کرد:
 enum Category{ Biography = 5, Poetry = 8, Fiction = 9 }; // 5, 8, 9
پس از اینکه نوع enum تعریف شده، استفاده از آن همانند سایر نوع‌های پایه‌ی TypeScript است:
 let favoriteCategory: Category = Category.Biography;
در اینجا متغیر favoriteCategory از نوع enum گروه کتاب‌ها تعیین شده‌است؛ با مقدار اولیه‌ی Category.Biography.
در این حالت اگر مقدار favoriteCategory را چاپ کنیم، خروجی عددی 5 نمایش داده می‌شود:
 console.log(favoriteCategory); // 5
اگر نیاز به بازگشت مقدار رشته‌ای این آیتم است، می‌توان از ایندکس‌های یک enum استفاده کرد:
let categoryString= Category[favoriteCategory]; // Biography


آرایه‌ها در TypeScript

در حالت عمومی، آرایه‌ها در TypeScript همانند جاوا اسکریپت تعریف می‌شوند؛ البته به همراه تعدادی استثناء. در TypeScript سه روش برای تعریف آرایه‌ها وجود دارند:
الف) در مثال زیر آرایه‌ای از رشته‌ها تعریف شده‌است. در اینجا نوع آرایه به همراه [] مشخص می‌شود:
let strArray1: string[] = ['here', 'are', 'strings'];
ب) روش دوم تعریف آرایه‌ها در TypeScript با استفاده از مفهوم Generics است که در بحثی جداگانه به آن خواهیم پرداخت. در اینجا از واژه‌ی کلیدی Array به همراه مشخص سازی نوع آن در داخل <> استفاده شده‌است:
let strArray2: Array<string> = ['more', 'strings', 'here'];
ج) اگر نیاز به آرایه‌هایی شبیه به جاوا اسکریپت دارید که می‌توانند حاوی انواع و اقسام المان‌هایی با نوع‌های مختلف باشند، نوع آرایه را []any تعریف کنید:
let anyArray: any[] = [42, true, 'banana'];


نوع Tuples در TypeScript

Tuples در TypeScript نوع خاصی از آرایه‌ها هستند که نوع مقادیر اعضای آن‌ها به صورت صریح مشخص می‌شوند:
 let myTuple: [number, string] = [25, 'truck'];
برای مثال در اینجا نوع متغیر myTuple به صورت آرایه‌ای از دو عنصر عددی و رشته‌ای تعریف شده‌است.
اکنون برای دسترسی به مقادیر این المان‌ها، همانند کار با آرایه‌های معمولی، از ایندکس‌های آرایه‌ی تعریف شده استفاده می‌شود:
 let firstElement= myTuple[0]; // 25
let secondElement= myTuple[1]; // truck

یک نکته: می‌توان به آرایه‌ی تعریف شده، عناصر جدیدی را نیز افزود؛ با این شرط که نوع آن‌ها، یکی از نوع‌های مشخص شده‌ی در تعریف Tuple باشند:
 // other elements can have numbers or strings
myTuple[2] = 100;
myTuple[2] = 'this works!';


مفهوم Type assertions در TypeScript

حتما با مفهوم cast و تبدیل نوع‌های مختلف به یکدیگر، در زبان‌های دیگر برنامه نویسی آشنا هستید. در TypeScript نیز این مفهوم تحت عنوان Type assertions پشتیبانی می‌شود و دو روش برای تعریف آن وجود دارد:
الف) تعریف cast توسط angle-bracket syntax که در آن نوع مدنظر داخل یک <> قرار می‌گیرد:
 let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
در اینجا نوع نامشخص any به string تبدیل شده و سپس امکان دسترسی به خاصیت طول آن که تحت کنترل کامپایلر است و قابل انتساب به یک مقدار عددی، میسر شده‌است.
ب) تعریف cast توسط as syntax به نحو ذیل:
 let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
هر دو حالت تعریف شده معادل هستند. فقط باید دقت داشت در حین کار با ReactJS توسط TypeScript، فقط حالت as syntax پشتیبانی می‌شود.
نظرات مطالب
یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017
یک نکته‌ی تکمیلی
Microsoft.DotNet.Web.Spa.ProjectTemplates  در آخرین نگارش آن، پشتیبانی از Angular CLI را هم افزوده‌است. برای کار با آن و ایجاد یک پروژه‌ی جدید بر مبنای آن دستورات ذیل را صادر کنید:
> dotnet new --install Microsoft.DotNet.Web.Spa.ProjectTemplates::2.0.0-preview1-final
> dotnet new angular
سپس اگر به فایل‌های Startup.cs و csproj آن دقت کنید، نحوه‌ی استفاده‌ی از بسته‌ی نیوگت Microsoft.AspNetCore.SpaServices.Extensions را جهت معرفی مسیر ClientApp/dist و راه اندازی خودکار UseAngularCliServer مشاهده خواهید کرد.

توضیحات بیشتر:
About The Updated SPA Templates From ASP.NET Core 
Migrating from the old ASP.NET Core Angular Spa template to the newer one