اشتراک‌ها
آموزش AngularJS از کمپانی لیندا
مدت زمان فیلم یک ساعت
سرفصلهای آموزش شامل :

Introduction
  Welcome
  What you need to know
Using the exercise files
  Using the challenges
1. Configuring a New Angular Project
  Why Angular?
  Downloading Angular and dependencies
  Developing an application boilerplate
  Starting a Node server
2. Templates
  Supplying scope data
  Filtering output
  Controlling scopes
  Including partials
  Challenge: Editing airports
  Solution: Editing airports
3. Application Structure
  Routing views
  Supplying navigation
  Nesting scopes
  Linking individual records
  Challenge: Displaying two airports
  Solution: Displaying two airports
4. Server-Side Integration
  Defining services
  Retrieving individual records
  Searching through models
  Saving form data
  Challenge: Combining multiple data sources
  Solution: Combining multiple data sources
Conclusion
  Exploring advanced techniques
  Finding Angular resources 
آموزش AngularJS از کمپانی لیندا
نظرات مطالب
قابلیت Attribute Routing در ASP.NET MVC 5
مطابق مقاله‌ای که ابتدای بحث لینک داده شده، امکان ترکیب هر دو حالت attribute routing و convention-based routing با هم وجود دارد و اگر در حالت قدیمی یعنی convention-based routing، شما مثل قبل یک default route تعریف کرده باشید، دیگر نیازی به ذکر و تکرار default route هم نام یک کنترلر در حالت attribute routing نخواهید داشت و فقط جایی که واقعا نیاز است باید از آن استفاده کرد. attribute routing کار رو برای تعریف قیدها یا constraints خیلی ساده و طبیعی کرده.
نظرات مطالب
سفارشی سازی ASP.NET Core Identity - قسمت پنجم - سیاست‌های دسترسی پویا
- لیست صفحاتی را که کاربر به آن دسترسی دارد، پس از لاگین برای او ارسال کنید (یا به صورت یک آرایه که در سمت Angular کش شود یا به صورت Claims سفارشی داخل توکن JWT او؛ مانند Claims سفارشی نقش‌ها که هم اکنون موجود است).
- سپس توسط یک محافظ مسیر سفارشی، دسترسی‌ها را از این آرایه خوانده و اعمال کنید. برای نمونه محافظ مسیر سفارشی یاد شده، بر اساس Claims مربوط به نقش‌های کاربر که پس از لاگین به سمت کلاینت ارسال می‌شوند، دسترسی به مسیرها را کنترل می‌کند.
اشتراک‌ها
بازنویسی Windows Admin Center‌ مایکروسافت با Angular 5

پس از نصب آن، برنامه‌ی Angular 5 آن‌را در مسیر C:\Program Files\Windows Admin Center\UX.zip خواهید یافت. همچنین مایکروسافت این برنامه‌ها را نیز بر مبنای Angular 5 تهیه کرده‌است:

- Microsofts streaming website (mixer.com)
-  Office portal
- Microsoft Store for Education
- Azure functions UI
 

بازنویسی Windows Admin Center‌ مایکروسافت با Angular 5
مطالب
Virtual Scrolling در Angular 7
یکی از امکانات Angular 7، ویژگی Virtual Scrolling می‌باشد. در صورتیکه شما قصد داشته باشید یک لیست بزرگ از المنت‌ها را  بارگذاری کنید، این‌کار می‌تواند بر روی کارآیی برنامه‌ی شما تاثیر بگذارد . تگ زیر
<cdk-virtual-scroll-viewport></cdk-virtual-scroll-viewport>
می تواند برای بارگذاری تنها بخش‌های قابل مشاهده‌ی از یک لیست، بر روی صفحه نمایش استفاده شود و همچنین تنها آیتم‌هایی Render خواهند شد که می‌تواند آن‌ها را در صفحه نمایش جا دهد. اگر لیست بارگذاری شده را اسکرول کنیم، در این حالت المنت‌ها در DOM  به صورت پویا  load و unload می‌شوند. 
قبل از پیاده سازی ، لازم است Angular CLI  را به آخرین نسخه بروز رسانی کنیم. برای بروز رسانی Angular CLI  دستور زیر را اجرا می‌کنیم:
npm install -g @angular/cli
بعد از نصب با استفاده از ng version  نسخه‌ی Angular CLI  را بررسی می‌کنیم که باید بزرگتر از 7 باشد:

حالا نوبت به ایجاد یک پروژه‌ی جدید می‌باشد. با استفاده از دستور زیر یک پروژه جدید ایجاد می‌شود:
ng new angular7-virtualScrolling
بعد از تایید دستور بالا،  دو سؤال از شما پرسیده می‌شود؟
1- آیا قصد دارید Angular routing اضافه شود یا نه؟ ( در نسخه‌های قبلی با استفاده از routing--  این کار را انجام می‌دادیم)


2-انتخاب فرمت stylesheet که قصد استفاده‌ی از آن‌را دارید ( با کلید‌های جهتی بالا و پایین روی صحفه کلید می‌توانید یکی از گزینه‌ها را انتخاب کنید )


برای استفاده از Virtual Scrolling نیاز است پکیج زیر را نصب کنیم : 
npm install @angular/cdk@latest
بعد از نصب، دستور ng serve را اجرا می‌کنیم تا بررسی کنیم که برنامه به درستی اجرا می‌شود یا نه. سپس فایل app.module.ts را باز می‌کنیم و ScrollingModule را در بخش imports اضافه می‌کنیم. اکنون نیاز است تا یک آرایه را برای نمایش آیتم‌های لیست، تولید کنیم. قطعه کد زیر در فایل app.component.ts  قرار دارد که یک آرایه عددی را ایجاد می‌کند و تعدادی آیتم را به آن اضافه می‌کند:
  title = 'Angular 7 – Virtual Scrolling feature';
  scrollItems: number[] = [];
  constructor() {
    for (let index = 0; index < 10000; index++) {
      this.scrollItems.push(index);
    }
  }

در فایل app.component.html  قطعه کد زیر را قرار می‌دهیم:
    <div>
      <h4>
        {{this.title}}
      </h4>
      <cdk-virtual-scroll-viewport itemSize="100">
        <div *cdkVirtualFor="let n of scrollItems">Item {{n}}</div>
      </cdk-virtual-scroll-viewport>
    </div>

داخل تگ  cdk-virtual-scroll-viewport، یک div را ایجاد و سپس یک دایرکتیو را به نام cdkVirtualFor* به آن اضافه می‌کنیم. این دایرکتیو، ngFor* را درون cdk-virtual-scroll-viewport، جایگزین می‌کند که شما با استفاده از آن می‌توانید یک حلقه بر روی آرایه  scrollItems  جهت پیمایش ایجاد کنید.
تمام ! اکنون پروژه را اجرا کنید.
در اولین بار اجرا :    


بعد از اسکرول کردن لیست : 


همانطور که مشاهده می‌کنیم المنت‌های قبلی unload شدند و المنت‌های جدید load شدند
DEMO 


نظرات مطالب
شروع به کار با AngularJS 2.0 و TypeScript - قسمت اول - نصب پیشنیازها
به روز رسانی: ارتقاء به نگارش «2.0.0rc.0 »

برای ارتقاء به نگارش RC0، این مراحل را باید طی کنید:
1) پیش از هر کاری، پوشه‌ی node_modules قدیمی خود را حذف کنید (با تمام محتوای آن).
2) به روز رسانی فایل package.json به صورت ذیل:
{
    "name": "asp-net-mvc5x-angular2x",
    "version": "1.0.0",
    "author": "DNT",
    "description": "",
    "scripts": {
        "postinstall": "typings install"
    },
    "license": "Apache-2.0",
    "dependencies": {
        "@angular/common": "^2.0.0-rc.0",
        "@angular/compiler": "^2.0.0-rc.0",
        "@angular/core": "^2.0.0-rc.0",
        "@angular/http": "2.0.0-rc.0",
        "@angular/router": "2.0.0-rc.0",
        "@angular/router-deprecated": "^2.0.0-rc.0",
        "@angular/platform-browser": "^2.0.0-rc.0",
        "@angular/platform-browser-dynamic": "^2.0.0-rc.0",
        "bootstrap": "^3.3.6",
        "es6-promise": "^3.1.2",
        "es6-shim": "^0.35.0",
        "jquery": "^2.2.3",
        "reflect-metadata": "^0.1.3",
        "rxjs": "^5.0.0-beta.6",
        "systemjs": "^0.19.27",
        "zone.js": "^0.6.12"
    },
    "devDependencies": {
        "typescript": "^1.8.9",
        "typings": "^0.8.1"
    },
    "repository": { }
}
به روز شده‌ی محتوای فوق، همیشه در آدرس مستندات npm packages موجود است.
3) افزودن فایلی به نام typings.json در ریشه‌ی پروژه؛ با این محتوا:
{
    "ambientDependencies": {
        "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd"
    }
}
این فایل توسط قسمت «postinstall» اسکریپت package.json نصب می‌شود. اما چون مسیر https://raw.githubusercontent.com قابل دسترسی نیست (از این طرف البته!)، موفق به دریافت آن نخواهید شد. بنابراین یک پوشه را به نام typings به ریشه‌ی سایت اضافه کنید و سپس فایل ذیل را به آن اضافه نمائید:
es6-shim.d.ts
بدون این فایل، کامپایلر TypeScript تعاریف ES 6 را مانند Map و Promise و امثال آن‌، نمی‌شناسد و پروژه را کامپایل نخواهد کرد.

اکنون یکبار فایل package.json را ذخیره کنید تا کار به روز رسانی بسته‌ها انجام شود. البته اگر بر روی این فایل کلیک راست کنید، در منوی ظاهر شده، گزینه‌ی restore packages هم موجود است.

4) پس از آن، چند تغییر جزئی ذیل باید در کدهای این سری، اعمال شوند:
هر جایی angular2 تعریف شده، اینبار می‌شود angular@. مثلا:
import { PipeTransform, Pipe } from '@angular/core';
فایل مسیریابی آن قرار است تغییرات کلی داشته باشد. این مورد به صورت ذیل تغییر نام یافته است:
import { RouteParams, Router } from '@angular/router-deprecated';
5) فایل main.ts (قسمت دوم) به صورت ذیل تغییر کرده‌است:
/// <reference path="../typings/es6-shim.d.ts" />
import { bootstrap } from '@angular/platform-browser-dynamic';

// Our main component
import { AppComponent } from "./app.component";

bootstrap(AppComponent);
6) تعاریف اسکریپت‌های Index.html سایت، اینبار به نحو ذیل تغییر کرده‌اند:
یک نکته: اگر می‌خواهید این تعاریف را در یک فایل razor، وارد کنید، چون @ به ابتدای پوشه‌ی angular2 اضافه شده (node_modules\@angular)، مشکل پردازشی razor را ایجاد خواهد کرد و باید escape شود. به همین جهت بجای @ بهتر است معادل آن را یعنی ("@")Html.Raw@   وارد کنید.
سپس ابتدا فایل systemjs.config.js را از اینجا دریافت کنید.
در ادامه مداخل جدید را هم در فایل index.html مثال رسمی آغازین آن بررسی کنید.

بنابراین، فایل systemjs.config.js را  به ریشه‌ی سایت اضافه کنید (از این جهت که مسیر بسته‌های node_modules را از ریشه‌ی سایت می‌خواند). سپس فایل Views\Shared\_Layout.cshtml را به نحو ذیل تغییر دهید:
<!DOCTYPE html>
<html>
<head>
    <base href="/">
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>

    <link href="~/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet"/>
    <link href="~/app/app.component.css" rel="stylesheet"/>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css"/>

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="~/node_modules/es6-shim/es6-shim.min.js"></script>

    <script src="~/node_modules/zone.js/dist/zone.js"></script>
    <script src="~/node_modules/reflect-metadata/Reflect.js"></script>
    <script src="~/node_modules/systemjs/dist/system.src.js"></script>

    <script src="~/systemjs.config.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
        System.import('app/main').then(null, console.error.bind(console));
    </script>
</head>
<body>
    <div>
        @RenderBody()
        <pm-app>Loading App...</pm-app>
    </div>

    @RenderSection("Scripts", required: false)
</body>
</html>

خلاصه‌ی سریع این موارد
الف) تغییرات آخرین بسته‌های npm را از مستندات آن پیگیری و اعمال کنید. آخرین نگارش آن همیشه در اینجا قابل دسترسی است.
ب) تغییرات index.html، فایل main.ts و مداخل آغازین آن‌را از مثال آغازین رسمی آن پیگیری و اعمال کنید.
نظرات نظرسنجی‌ها
آیا به یادگیری یا ادامه‌ی استفاده از AngularJS خواهید پرداخت؟
AngularJS فریم ورک خوبیه، ولی مشکلات زیادی داره. اول از همه اینکه در فاز تحقیقاتی هست و بر خلاف ادعا هایی که وجود داره Google در محصولات یا پروژه‌های داخلیش ازش استفاده نمی‌کنه. ثانیا تا اوایل سال 2016 انتشار مهمی (major release) نخواهیم دید و نسخه 2.0 فریم ورک کاملا جدیدی خواهد بود. بنابراین نه تنها backward compatibility نخواهیم داشت بلکه تمام تجربه و دانش فعلی عملا بلا استفاده خواهند بود و باید همه چیز رو از ابتدا یاد گرفت. باید منتظر بود تا نسخه بعدی منشر بشه و اگر اون موقع تیم Angular تونست نسبت به رقبای دیگش حرف اول رو بزنه، می‌تونیم بریم سراغش و فریم ورک‌های دیگه رو کنار بگذاریم.

در نگاه اول شاید برای توسعه دهندگان مبتدی یک سری مباحث گیج کننده باشن و خیلی از قابلیت‌ها هم جادویی و جذاب. اما حقیقت امر این است که code base این فریم ورک مشکلات شگفت آوری داره. چند ساعت وقت گذاشتن روی اینترنت کافی هست تا از تمام جنبه‌ها فریم ورک‌های مطرح رو بررسی کرد و متوجه شد که Angular چقدر مشکلات اساسی داره. بصورت تیتر وار چند مورد رو لیست می‌کنم:
  • Dynamic Scoping, and scope inheritance
  • Two-way data binding with $watchers
  • The $digest cycle
  • No DOM manipulation capabilities
  • Finite Routing, unless you use a 3rd party like ui-router
  • app logic and structure expressed in HTML
  • No server-side rendering (mostly for speed boost and SEO)
  • string-based Dependency Injection
  • Ill-Conceived architecture (obsolete constructor functions etc)
  • Debugging issues
  • Re-defining well established terminology
  • Syntactic Sugar
  • Execution Contexts
  • Unnecessary Complications
  • Incompatible with 3rd party libraries, like jQuery etc.
  • Sparse documentation with literally no real-world examples

و مواردی از این دست. شاید برای پروژه‌های کوچک این فریم ورک مناسب باشه اما قطعا برای پروژه‌های بزرگی که قرار است برای مدتی طولانی توسعه داده بشن و نگهداری بشن اصلا انتخاب درستی نیست. حتی اگر پروژه‌های بزرگی هم با موفقیت توسط این فریم اجرا شده باشه باز هم ماهیت مساله تغییر نمی‌کنه.

در حال حاظر بین فریم ورک‌های دیگه بهترین انتخاب Ember هست که بسیاری از مشکلات ذکر شده رو نداره و ساختار و معماری قوی و خوبی هم داره. Backbone و Durandal هم فریم ورک‌های قوی ای هستند ولی تفاوت‌های نسبتا زیادی با Ember دارن.

حائز اهمیت این که، اپلیکیشن‌های SPA جوان هستند و فعلا همه جای دنیا در حال آزمایش و بررسی این هستند که چطور میشه چنین پروژه هایی رو اجرا کرد و کدام راه بهترین راه هست، بنابراین تا به استاندارد‌های ثابتی برسیم راه طولانی ای در پیش داریم. از طرفی بزودی استاندارد جدید جاوا اسکریپت (ECMA6) منتشر میشه، که با انتشارش فریم ورک هایی مثل Ember و Angular رو کاملا به هم خواهد ریخت. مثلا در نسخه جدید آبجکت‌های Observable خواهیم داشت. بنابراین متدهای Angular و Ember برای تشخیص تغییرات به کلی بلا استفاده خواهند بود و بازنویسی‌های اساسی لازم می‌شود.

مطالب
یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017
در این مطلب مثالی را در مورد نحوه‌ی تنظیمات یک پروژه‌ی خالی ASP.NET Core، جهت استفاده‌ی از یک پروژه‌ی Angular CLI قرار گرفته‌ی در پوشه‌ی آن‌را بررسی خواهیم کرد.

پیشنیازها

 - مطالعه‌ی سری کار با Angular CLI خصوصا قسمت نصب و قسمت ساخت برنامه‌های آن، پیش از مطالعه‌ی این مطلب ضروری است.
 - همچنین فرض بر این است که سری ASP.NET Core را نیز یکبار مرور کرده‌اید و با نحوه‌ی برپایی یک برنامه‌ی MVC آن و ارائه‌ی فایل‌های استاتیک توسط یک پروژه‌ی ASP.NET Core آشنایی دارید.


ایجاد یک پروژه‌ی جدید ASP.NET Core در VS 2017

در ابتدا یک پروژه‌ی خالی ASP.NET Core را در VS 2017 ایجاد خواهیم کرد. برای این منظور:
 - ابتدا از طریق منوی File -> New -> Project (Ctrl+Shift+N) گزینه‌ی ایجاد یک ASP.NET Core Web application را انتخاب کنید.
 - در صفحه‌ی بعدی آن هم گزینه‌ی «empty template» را انتخاب نمائید.


تنظیمات یک برنامه‌ی ASP.NET Core خالی برای اجرای یک برنامه‌ی Angular CLI

برای اجرای یک برنامه‌ی مبتنی بر Angular CLI، نیاز است بر روی فایل csproj برنامه‌ی ASP.NET Core کلیک راست کرده و گزینه‌ی Edit آن‌را انتخاب کنید.
سپس محتوای این فایل را به نحو ذیل تکمیل نمائید:

الف) درخواست عدم کامپایل فایل‌های TypeScript
  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
  </PropertyGroup>
چون نحوه‌ی کامپایل پروژه‌های Angular CLI صرفا مبتنی بر کامپایل مستقیم فایل‌های TypeScript آن نیست و در اینجا از یک گردش کاری توکار مبتنی بر webpack، به صورت خودکار استفاده می‌کند، کامپایل فایل‌های TypeScript توسط ویژوال استودیو، مفید نبوده و صرفا سبب دریافت گزارش‌های خطای بیشماری به همراه کند کردن پروسه‌ی Build آن خواهد شد. بنابراین با افزودن تنظیم TypeScriptCompileBlocked به true، از VS 2017 خواهیم خواست تا در این زمینه دخالت نکند.

ب) مشخص کردن پوشه‌هایی که باید الحاق و یا حذف شوند
  <ItemGroup>
    <Folder Include="Controllers\" />
    <Folder Include="wwwroot\" />
  </ItemGroup>
 
  <ItemGroup>
    <Compile Remove="node_modules\**" />
    <Content Remove="node_modules\**" />
    <EmbeddedResource Remove="node_modules\**" />
    <None Remove="node_modules\**" />
  </ItemGroup>
 
  <ItemGroup>
    <Compile Remove="src\**" />
    <Content Remove="src\**" />
    <EmbeddedResource Remove="src\**" />    
  </ItemGroup>
در اینجا پوشه‌های کنترلرها و wwwroot به پروژه الحاق شده‌اند. پوشه‌ی wwwroot جایی است که فایل‌هایی خروجی را Angular CLI ارائه خواهد کرد.
سپس دو پوشه‌ی node_modules و src واقع در ریشه‌ی پروژه را نیز به طور کامل از سیستم ساخت و توزیع VS 2017 حذف کرده‌ایم. پوشه‌ی node_modules وابستگی‌های Angular را به همراه دارد و src همان پوشه‌ی برنامه‌ی Angular ما خواهد بود.

ج) افزودن وابستگی‌های سمت سرور مورد نیاز
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
  </ItemGroup>
 
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" />
  </ItemGroup>
 
  <ItemGroup>
    <!-- extends watching group to include *.js files -->
    <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" />
  </ItemGroup>
برای اجرای یک برنامه‌ی تک صفحه‌ای وب Angular، صرفا به وابستگی MVC و StaticFiles آن نیاز است.
در اینجا Watcher.Tools هم به همراه تنظیمات آن اضافه شده‌اند که در ادامه‌ی بحث به آن اشاره خواهد شد.


افزودن یک کنترلر Web API جدید

با توجه به اینکه دیگر در اینجا قرار نیست با فایل‌های cshtml و razor کار کنیم، کنترلرهای ما نیز از نوع Web API خواهند بود. البته در ASP.NET Core، کنترلرهای معمولی آن، توانایی ارائه‌ی Web API و همچنین فایل‌های Razor را دارند و از این لحاظ تفاوتی بین این دو نیست و یکپارچگی کاملی صورت گرفته‌است.
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
 
namespace ASPNETCoreIntegrationWithAngularCLI.Controllers
{
  [Route("api/[controller]")]
  public class ValuesController : Controller
  {
    // GET: api/values
    [HttpGet]
    [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
    public IEnumerable<string> Get()
    {
      return new string[] { "Hello", "DNT" };
    }
  }
}
در اینجا کدهای یک کنترلر نمونه را جهت بازگشت یک خروجی JSON ساده مشاهده می‌کنید که در ادامه، در برنامه‌ی Angular CLI تهیه شده از آن استفاده خواهیم کرد.


تنظیمات فایل آغازین یک برنامه‌ی ASP.NET Core جهت ارائه‌ی برنامه‌های Angular

در ادامه به فایل Startup.cs برنامه‌ی خالی جاری، مراجعه کرده و آن‌را به نحو ذیل تغییر دهید:
using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
 
namespace ASPNETCoreIntegrationWithAngularCLI
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }
 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();
 
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
 
            app.Use(async (context, next) => {
                await next();
                if (context.Response.StatusCode == 404 &&
                    !Path.HasExtension(context.Request.Path.Value) &&
                    !context.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase))
                {
                    context.Request.Path = "/index.html";
                    await next();
                }
            });
 
            app.UseMvcWithDefaultRoute();
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }
    }
}
در اینجا برای ارائه‌ی کنترلر Web API، نیاز به ثبت سرویس‌های MVC است. همچنین ارائه‌ی فایل‌های پیش فرض و فایل‌های استاتیک (همان پوشه‌ی wwwroot برنامه) نیز فعال شده‌اند.
در قسمت app.Use آن، تنظیمات URL Rewriting مورد نیاز جهت کار با مسیریابی برنامه‌های Angular را مشاهده می‌کنید. برای نمونه اگر کاربری در ابتدای کار آدرس /products را درخواست کند، این درخواست به سمت سرور ارسال می‌شود و چون چنین صفحه‌ای در سمت سرور وجود ندارد، خطای 404 بازگشت داده می‌شود و کار به پردازش برنامه‌ی Angular نخواهد رسید. اینجا است که تنظیم میان‌افزار فوق، کار مدیریت خروجی‌های 404 را بر عهده گرفته و کاربر را به فایل index.html برنامه‌ی تک صفحه‌ای وب، هدایت می‌کند. به علاوه در اینجا اگر درخواست وارد شده، دارای پسوند باشد (یک فایل باشد) و یا با api/ شروع شود (اشاره کننده‌ی به کنترلرهای Web API برنامه)، از این پردازش و هدایت به صفحه‌ی index.html معاف خواهد شد.


ایجاد ساختار اولیه‌ی برنامه‌ی Angular CLI در داخل پروژه‌ی جاری

اکنون از طریق خط فرمان به پوشه‌ی ریشه‌ی برنامه‌ی ASP.NET Core‌، جائیکه فایل Startup.cs قرار دارد، وارد شده و دستور ذیل را اجرا کنید:
 >ng new ClientApp --routing --skip-install --skip-git --skip-commit
به این ترتیب پوشه‌ی جدید ClientApp، در داخل پوشه‌ی برنامه اضافه خواهد شد که در آن تنظیمات اولیه‌ی مسیریابی Angular نیز انجام شده‌است؛ از دریافت وابستگی‌های npm آن صرفنظر شده و همچنین کار تنظیمات git آن نیز صورت نگرفته‌است (تا از تنظیمات git پروژه‌ی اصلی استفاده شود).
پس از تولید ساختار برنامه‌ی Angular CLI، به پوشه‌ی آن وارد شده و تمام فایل‌های آن را Cut کنید. سپس به پوشه‌ی ریشه‌ی برنامه‌ی ASP.NET Core جاری، وارد شده و این فایل‌ها را در آنجا paste نمائید. به این ترتیب به حداکثر سازگاری ساختار پروژه‌های Angular CLI و VS 2017 خواهیم رسید. زیرا اکثر فایل‌های تنظیمات آن‌را می‌شناسد و قابلیت پردازش آن‌ها را دارد.
پس از این cut/paste، پوشه‌ی خالی ClientApp را نیز حذف کنید.


تنظیم محل خروجی نهایی Angular CLI به پوشه‌ی wwwroot

برای اینکه سیستم Build پروژه‌ی Angular CLI جاری، خروجی خود را در پوشه‌ی wwwroot قرار دهد، تنها کافی است فایل .angular-cli.json را گشوده و outDir آن‌را به wwwroot تنظیم کنیم:
"apps": [
    {
      "root": "src",
      "outDir": "wwwroot",
به این ترتیب پس از هر بار build آن، فایل‌های index.html و تمام فایل‌های js نهایی، در پوشه‌ی wwwroot که در فایل Startup.cs‌، کار عمومی کردن آن انجام شد، تولید می‌شوند.


فراخوانی کنترلر Web API برنامه در برنامه‌ی Angular CLI

در ادامه صرفا جهت آزمایش برنامه، فایل src\app\app.component.ts را گشوده و به نحو ذیل تکمیل کنید:
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http'; 
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor(private _httpService: Http) { }
 
  apiValues: string[] = [];
 
  ngOnInit() {
    this._httpService.get('/api/values').subscribe(values => {
      this.apiValues = values.json() as string[];
    });
  }
}
در اینجا خروجی JSON کنترلر Web API برنامه دریافت شده و به آرایه‌ی apiValues انتساب داده می‌شود.

سپس این آرایه را در فایل قالب این کامپوننت (src\app\app.component.html) استفاده خواهیم کرد:
<h1>Application says:</h1>
<ul *ngFor="let value of apiValues">
  <li>{{value}}</li>
</ul>
<router-outlet></router-outlet>
در اینجا یک حلقه ایجاد شده و عناصر آرایه‌ی apiValues به صورت یک لیست نمایش داده می‌شوند.


نصب وابستگی‌های برنامه‌ی Angular CLI

در ابتدای ایجاد پوشه‌ی ClientApp، از پرچم skip-install استفاده شد، تا صرفا ساختار پروژه، جهت cut/paste آن با سرعت هر چه تمام‌تر، ایجاد شود. اکنون برای نصب وابستگی‌های آن یا می‌توان در solution explorer به گره dependencies مراجعه کرده و npm را انتخاب کرد. در ادامه با کلیک راست بر روی آن، گزینه‌ی restore packages ظاهر می‌شود. و یا می‌توان به روش متداول این نوع پروژه‌ها، از طریق خط فرمان به پوشه‌ی ریشه‌ی پروژه وارد شد و دستور npm install را صادر کرد. بهتر است اینکار را از طریق خط فرمان انجام دهید تا مطمئن شوید که از آخرین نگارش‌های این ابزار که بر روی سیستم نصب شده‌است، استفاده می‌کنید.


روش اول اجرای برنامه‌های مبتنی بر ASP.NET Core و Angular CLI

تا اینجا اگر برنامه را از طریق VS 2017 اجرا کنید، خروجی را مشاهده نخواهید کرد. چون هنوز فایل index.html آن تولید نشده‌است.
بنابراین روش اول اجرای این نوع برنامه‌ها، شامل مراحل ذیل است:
الف) ساخت پروژه‌ی Angular CLI در حالت watch
 > ng build --watch
برای اجرای آن از طریق خط فرمان، به پوشه‌ی ریشه‌ی پروژه وارد شده و دستور فوق را وارد کنید. به این ترتیب کار build پروژه انجام شده و همچنین فایل‌های نهایی آن در پوشه‌ی wwwroot قرار می‌گیرند. به علاوه چون از پرچم watch استفاده شده‌است، با هر تغییری در پوشه‌ی src برنامه، این فایل‌ها به صورت خودکار به روز رسانی می‌شوند. بنابراین این پنجره‌ی خط فرمان را باید باز نگه داشت تا watcher آن بتواند کارش را به صورت مداوم انجام دهد.

ب) اجرای برنامه از طریق ویژوال استودیو
اکنون که کار ایجاد محتوای پوشه‌ی wwwroot برنامه انجام شده‌است، می‌توان برنامه را از طریق VS 2017 به روش متداولی اجرا کرد:


یک نکته: می‌توان قسمت الف را تبدیل به یک Post Build Event هم کرد. برای این منظور باید فایل csproj را به نحو ذیل تکمیل کرد:
<Target Name="AngularBuild" AfterTargets="Build">
    <Exec Command="ng build" />
</Target>
به این ترتیب با هربار Build پروژه در VS 2017، کار تولید مجدد محتوای پوشه‌ی wwwroot نیز انجام خواهد شد.
تنها مشکل روش Post Build Event، کند بودن آن است. زمانیکه از روش ng build --watch به صورت مستقل استفاده می‌شود، برای بار اول اجرا، اندکی زمان خواهد برد؛ اما اعمال تغییرات بعدی به آن بسیار سریع هستند. چون صرفا نیاز دارد این تغییرات اندک و تدریجی را کامپایل کند و نه کامپایل کل پروژه را از ابتدا.


روش دوم اجرای برنامه‌های مبتنی بر ASP.NET Core و Angular CLI

روش دومی که در اینجا بررسی خواهد شد، مستقل است از قسمت «ب» روش اول که توضیح داده شد. برنامه‌های NET Core. نیز به همراه CLI خاص خودشان هستند و نیازی نیست تا حتما از VS 2017 برای اجرای آن‌ها استفاده کرد. به همین جهت وابستگی Microsoft.DotNet.Watcher.Tools را نیز در ابتدای کار به وابستگی‌های برنامه اضافه کردیم.

الف) در ادامه، VS 2017 را به طور کامل ببندید؛ چون نیازی به آن نیست. سپس دستور ذیل را در خط فرمان، در ریشه‌ی پروژه‌، صادر کنید:
> dotnet watch run
این دستور پروژه‌ی ASP.NET Core را کامپایل کرده و بر روی پورت 5000 ارائه می‌دهد:
>dotnet watch run
[90mwatch : [39mStarted
Hosting environment: Production
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
به علاوه پارامتر watch آن سبب خواهد شد تا هر تغییری که در کدهای پروژه‌ی ASP.NET Core صورت گیرند، بلافاصله کامپایل شده و قابل استفاده شوند.

ب) در اینجا چون برنامه بر روی پورت 5000 ارائه شده‌است، بهتر است دستور ng serve -o را صادر کرد تا بتوان به نحو ساده‌تری از سرور وب ASP.NET Core استفاده نمود. در این حالت برنامه‌ی Angular CLI بر روی پورت 4200 ارائه شده و بلافاصله در مرورگر نیز نمایش داده می‌شود.
مشکل! سرور وب ما بر روی پورت 5000 است و سرور آزمایشی Angular CLI بر روی پورت 4200. اکنون برنامه‌ی Angular ما، یک چنین درخواست‌هایی را به سمت سرور، جهت دریافت اطلاعات ارسال می‌کند: localhost:4200/api
برای رفع این مشکل می‌توان فایلی را به نام proxy.config.json با محتویات ذیل ایجاد کرد:
{
  "/api": {
    "target": "http://localhost:5000",
    "secure": false
  }
}
سپس دستور ng server صادر شده، اندکی متفاوت خواهد شد:
 >ng serve --proxy-config proxy.config.json -o
در اینجا به ng serve اعلام کرده‌ایم که تمامی درخواست‌های ارسالی به مسیر api/  (و یا همان localhost:4200/api جاری) را به سرور وب ASP.NET Core، بر روی پورت 5000 ارسال کن و نتیجه را در همینجا بازگشت بده. به این ترتیب مشکل عدم دسترسی به سرور وب، جهت تامین اطلاعات برطرف خواهد شد.
مزیت این روش، به روز رسانی خودکار مرورگر با انجام هر تغییری در کدهای قسمت Angular برنامه است.

نکته 1: بدیهی است می‌توان قسمت «ب» روش دوم را با قسمت «الف» روش اول نیز جایگزین کرد (ساخت پروژه‌ی Angular CLI در حالت watch). اینبار گشودن مرورگر بر روی پورت 5000 (و یا آدرس http://localhost:5000) را باید به صورت دستی انجام دهید. همچنین هربار تغییر در کدهای Angular، سبب refresh خودکار مرورگر نیز نمی‌شود که آن‌را نیز باید خودتان به صورت دستی انجام دهید (کلیک بر روی دکمه‌ی refresh پس از هر بار پایان کار ng build).
نکته 2: می‌توان قسمت «الف» روش دوم را حذف کرد (حذف dotnet run در حالت watch). یعنی می‌خواهیم هنوز هم ویژوال استودیو کار آغاز IIS Express را انجام دهد. به علاوه می‌خواهیم برنامه را توسط ng serve مشاهده کنیم (با همان پارامترهای قسمت «ب» روش دوم). در این حالت تنها موردی را که باید تغییر دهید، پورتی است که برای IIS Express تنظیم شده‌است. عدد این پورت را می‌توان در فایل Properties\launchSettings.json مشاهده کرد و سپس به تنظیمات فایل proxy.config.json اعمال نمود.


کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید: ASPNETCoreIntegrationWithAngularCLI.zip
به همراه این کدها تعدادی فایل bat نیز وجود دارند که جهت ساده سازی عملیات یاد شده‌ی در این مطلب، می‌توان از آن‌ها استفاده کرد:
 - فایل restore.bat کار بازیابی و نصب وابستگی‌های پروژه‌ی دات نتی و همچنین Angular CLI را انجام می‌دهد.
 - دو فایل ng-build-dev.bat و ng-build-prod.bat بیانگر قسمت «الف» روش اول هستند. فایل dev مخصوص حالت توسعه است و فایل prod مخصوص ارائه‌ی نهایی.
 - دو فایل dotnet_run.bat و ng-serve-proxy.bat خلاصه کننده‌ی قسمت‌های «الف» و «ب» روش دوم هستند.