نظرات مطالب
سازماندهی برنامه‌های Angular توسط ماژول‌ها
سلام ؛ اگر قرار باشد کلیه روتهای برنامه به عنوان childrout‌های والدی مثلا pages باشند از آنجا که برنامه حاوی چندین feature modules است تعریف همه  روتها در app-routing باشد ؟ یا در featureX-routing  ؟ (روت والد دارای کامپوننت page-component می‌باشد و منظور گروه بندی  تنها نیست . ) با تشکر .
مطالب
ایجاد پروژه‌ی «کتابخانه» توسط Angular CLI 6.0
یکی از مواردی که با Angular CLI 6.0 به شدت ساده شده‌است، ایجاد پروژه‌های «کتابخانه» Angular است. برای مثال شاید در حین استفاده‌ی از بعضی از کتابخانه‌ی ثالث تهیه شده‌ی برای Angular با خطای ذیل مواجه شده باشید:
Please open an issue in the library repository to alert its author and ask them to 
package the library using the Angular Package Format (https://goo.gl/jB3GVv).
این خطا زمانی رخ می‌دهد که تهیه کننده‌ی کتابخانه، فرمت بسته‌های Angular را رعایت نکرده باشد و ... رعایت کردن آن نیز کار بسیار مشکلی است. نگارش 6 در پشت صحنه، پروژه‌ی موفق ng-packagr را به مجموعه‌ی CLI اضافه کرده‌است و از این پس توسط خود CLI می‌توان کتابخانه‌های استاندارد Angular را تولید کرد. این مورد، مزیت استاندارد سازی کتابخانه‌ها‌ی npm حاصل را نیز به همراه دارد. مشکلی که گاهی از اوقات به علت عدم رعایت این ساختار با بسته‌های فعلی npm مخصوص Angular وجود دارند؛ مانند خطایی که عنوان شد. برای مثال بدون استفاده‌ی از این ابزار، نیاز است مستندات چند صفحه‌ای ساخت کتابخانه‌های Angular را سطر به سطر پیاده سازی کنید که توسط CLI 6.0 به صورت خودکار ایجاد و مدیریت می‌شود.


مراحل ایجاد یک پروژه‌ی «کتابخانه» توسط Angular CLI 6.0

مرحله‌ی اول ایجاد یک پروژه‌ی کتابخانه، مانند قبل، توسط دستور ng new و ایجاد یک پروژه‌ی دلخواه جدید است:
 ng new my-lib-test
به همراه Angular CLI 6.0، فرمت تنظیمات آن نیز تغییر کرده‌است و مفهوم workspace به آن اضافه شده‌است که در آن می‌توان چندین پروژه را تعریف کرد.
پس از ایجاد پروژه‌ی my-lib-test توسط دستور فوق و وارد شدن به پوشه‌ی اصلی آن توسط خط فرمان، می‌توان با اجرای دستور زیر، پروژه‌های دیگری را به پروژه‌ی جاری افزود:
 ng generate application my-app-name
اما اگر در اینجا بجای ذکر application، از نام library استفاده کنیم، یک کتابخانه را بجای یک برنامه، به workspace جاری اضافه می‌کند:
 ng generate library my-lib
پس از اجرای این دستور اگر به فایل angular.json دقت کنیم، این پروژه در ذیل projects اضافه شده‌است:


همچنین یک پوشه‌ی جدید به نام projects نیز ایجاد شده و پروژه‌ی my-lib داخل آن قرار گرفته‌است.


فایل جدید public_api.ts

پس از ایجاد کتابخانه‌ی جدید «my-lib»، فایل جدیدی به نام projects\my-lib\src\public_api.ts نیز به آن اضافه شده‌است:


با این محتوا:
/*
* Public API Surface of my-lib
*/
export * from './lib/my-lib.service';
export * from './lib/my-lib.component';
export * from './lib/my-lib.module';
هر خروجی که در اینجا ذکر شود توسط استفاده کنندگان از این کتابخانه قابل دسترسی خواهد بود. برای مثال دستور «ng generate library my-lib» مطابق تصویر فوق، یک سرویس جدید را به نام my-lib.service، یک کامپوننت جدید را به نام my-lib.component و یک ماژول جدید را به نام my-lib.module به صورت پیش‌فرض ایجاد کرده و درون پوشه‌ی lib قرار داده‌است. اکنون آن‌ها را توسط فایل public_api.ts، به نحوی که مشاهده می‌کنید در معرض دید استفاده کنندگان قرار می‌دهد.
برای مثال اگر فایل جدید projects\my-lib\src\lib\my-lib.models.ts را به این کتابخانه اضافه کنیم که شامل تعدادی مدل و اینترفیس قابل دسترسی توسط استفاده کنندگان باشد، باید یک سطر زیر را به انتهای فایل public_api.ts اضافه کنیم:
 export * from './lib/my-lib.models';

این پروژه‌ی کتابخانه حتی به همراه فایل‌های package.json, tsconfig.json, tslint.json مخصوص به خود نیز می‌باشد تا بتوان آن‌ها را صرفا جهت این پروژه سفارشی سازی کرد.


ساختار my-lib.service پیش‌فرض یک پروژه‌ی کتابخانه

اگر به فایل projects\my-lib\src\lib\my-lib.service.ts دقت کنیم:
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyLibService {

  constructor() { }
}
تمام قسمت‌های آن مانند قبل است، منهای 'providedIn: 'root آن. این مورد تنظیم جدیدی است که در پروژه‌های Angular 6 قابل استفاده‌است. هدف از آن، ارائه‌ی یک سرویس، بدون نیاز به ثبت صریح آن در قسمت providers یک NgModule است.
شاید بپرسید چرا؟ هدف اصلی از آن، بهبود فرآیند tree-shaking یا حذف کدهای مرده و استفاده نشده‌است. ممکن است سرویسی را تعریف کنید، اما در برنامه استفاده نشود. این حالت خصوصا در پروژه‌های کتابخانه‌های ثالث ممکن است زیاد رخ دهد. به همین جهت با ارائه‌ی این قابلیت، امکان حذف ساده‌تر سرویس‌هایی که در برنامه استفاده نشده‌اند از خروجی نهایی کامپایل شده، وجود خواهد داشت.


چگونه به پروژه‌ی کتابخانه‌ی جدید، یک کامپوننت جدید را اضافه کنیم؟

تمام دستورات Angular CLI، در اینجا نیز کار می‌کنند. تنها تفاوت آن‌ها، ذکر صریح نام پروژه‌ی مورد استفاده است:
 ng generate component show-data --project=my-lib
دستور فوق کامپوننت جدید show-data را به پروژه‌ی my-lib اضافه خواهد کرد؛ به همراه به روز رسانی خودکار فایل projects/my-lib/src/lib/my-lib.module.ts این پروژه، جهت ثبت کامپوننت اضافه شده.
البته در اینجا باید فایل my-lib.module.ts را اندکی ویرایش کرد و ShowDataComponent را به قسمت exports نیز افزود:
@NgModule({
  imports: [
    CommonModule,
    HttpClientModule
  ],
  declarations: [MyLibComponent, ShowDataComponent],
  exports: [MyLibComponent, ShowDataComponent]
})
export class MyLibModule { }
به صورت پیش‌فرض، کامپوننت جدید را در قسمت declarations معرفی می‌کند. یک چنین کامپوننتی فقط داخل همان lib قابل استفاده‌است. اگر قرار است خارج از این lib نیز به آن دسترسی داشته باشیم، باید آن‌را در قسمت exports نیز قید کنیم.
همچنین قسمت imports آن نیز به صورت پیش‌فرض خالی است. اگر نیاز است با ngIf کار کنید، باید CommonModule را در اینجا قید کنید و اگر نیاز است تبادلات HTTP وجود داشته باشد، ذکر HttpClientModule نیز ضروری است.


مرحله‌ی ساخت پروژه

پیش از استفاده‌ی از این پروژه‌ی کتابخانه، باید آن‌را build کرد:
 ng build my-lib
در اینجا نیز دستور ng build مانند قبل است، با این تفاوت که نام پروژه‌ی کتابخانه نیز در اینجا ذکر شده‌است.
پس از اجرای این دستور، خروجی ذیل مشاهده می‌شود:
Building Angular Package
Building entry point 'my-lib'
Rendering Stylesheets
Rendering Templates
Compiling TypeScript sources through ngc
Downleveling ESM2015 sources through tsc
Bundling to FESM2015
Bundling to FESM5
Bundling to UMD
Minifying UMD bundle
Remap source maps
Relocating source maps
Copying declaration files
Writing package metadata
Removing scripts section in package.json as it's considered a potential security vulnerability.
Built my-lib
Built Angular Package!
- from: D:\my-lib-test\projects\my-lib
- to: D:\my-lib-test\dist\my-lib
همانطور که ملاحظه می‌کنید، پس از طی مراحل خاص تولید یک کتابخانه، خروجی نهایی آن‌را در پوشه‌ی dist\my-lib قرار داده‌است.


استفاده‌ی از کتابخانه‌ی تولید شده

پس از پایان موفقیت آمیز مرحله‌ی Build، اکنون نوبت به استفاده‌ی از این کتابخانه است. استفاده‌ی از آن نیز همانند تمام کتابخانه‌ها و وابستگی‌های ثالثی است که تا پیش از این از آن‌ها استفاده کرده‌ایم. برای مثال ماژول آن‌را در قسمت imports مربوط به NgModule کلاس AppModule معرفی می‌کنیم. برای این منظور به فایل src\app\app.module.ts مراجعه کرده و MyLibModule را به نحو ذیل اضافه می‌کنیم:
import { MyLibModule } from "my-lib";

@NgModule({
  imports: [
    BrowserModule,
    MyLibModule
  ]
})
export class AppModule { }
نکته‌ی مهمی که در اینجا باید به آن دقت داشت این است که هرچند در این پروژه، MyLibModule داخل پوشه‌ی projects\my-lib\src\lib قرار دارد، اما نباید مسیر نسبی آن‌را در اینجا ذکر کرد و باید صرفا نام پوشه‌ی my-lib واقع در پوشه‌ی node_modules را در اینجا در حین مسیر دهی import آن معرفی کرد (همانند تمام وابستگی‌های ثالث دیگر).
اما سؤال اینجا است که آیا این پوشه پس از build، داخل پوشه‌ی node_modules نیز کپی شده‌است؟ پاسخ آن خیر است و برای مدیریت خودکار آن، به صورت زیر عمل شده‌است:
اگر به فایل tsconfig.json اصلی و واقع در ریشه‌ی workspace دقت کنید، پس از اجرای دستور «ng generate library my-lib»، قسمت paths آن نیز به صورت خودکار ویرایش شده‌است:
{
  "compilerOptions": {
    "paths": {
      "my-lib": [
        "dist/my-lib"
      ]
    }
  }
}
معنای آن این است که هرگاه import ایی در برنامه به my-lib اشاره کند، کامپایلر TypeScript می‌داند که باید آن‌را از پوشه‌ی dist/my-lib دریافت و پردازش کند. به همین جهت در اینجا دیگر نیازی به کپی دستی این پوشه، به پوشه‌ی node_modules وجود ندارد.

برای نمونه اگر شاره‌گر ماوس را بر روی my-lib قرار دهید، به درستی مسیر خوانده شدن آن، تشخیص داده می‌شود.

به این ترتیب مسیر این import‌، چه در این پروژه‌ی محلی و چه برای کسانیکه پوشه‌ی dist/my-lib را به صورت یک بسته‌ی npm جدید دریافت کرده‌اند، یکی خواهد بود.

در ادامه اگر به فایل app.component.html مراجعه کرده و selector کامپوننت show-data را به آن اضافه کنیم:
 <lib-show-data></lib-show-data>
می‌توان محتویات این کامپوننت دریافت شده‌ی از کتابخانه را مشاهده کرد.


توزیع کتابخانه‌ی ایجاد شده برای عموم

برای اینکه این کتابخانه‌ی تولیدی را در اختیار عموم، در سایت npm قرار دهیم، ابتدا باید کتابخانه را در حالت production build تولید و سپس آن‌را publish کرد:
ng build my-lib --prod
cd dist/my-lib
npm publish
سطر اول، کتابخانه‌ی my-lib را در حالت production تواید می‌کند. سپس به پوشه‌ی فایل‌های نهایی تولید شده وارد می‌شویم و دستور npm publish را صادر می‌کنیم.
البته دستور آخر نیاز به ایجاد یک اکانت در سایت npm و وارد شدن به آن‌را دارد. جزئیات بیشتر آن در اینجا.
مطالب
فیلترها در WCF Routing Service
در پست قبلی توضیحات کلی درباره WCF Routing Service داده شد و یک مثال را نیز با هم بررسی کردیم. همان طور که در مثال مشاهده شد با استفاده از تعاریف فیلتر در جدول فیلتر‌ها توانستیم درخواست‌های مورد نظر را به مقاصد مربوطه اتصال دهیم. در این پست نگاه عمیق‌تری به FilterTable خواهیم داشت.

MessageFilter ها:
با استفاده از این نوع، می‌توان فیلتر مورد نظر را بر روی Message گسترش داد. برای مثال ارزیابی نام فرستنده Message یا حتی نوع عملیات Soap. حتی می‌توانیم فیلتر‌ها را با استفاده از And  با هم ترکیب نماییم.
FilterType ها
این enum دارای مقادیر زیر است:
  • Action : با استفاده ActionMessageFilter فیلتر مورد نظر انجام می‌شود.
  • And : با استفاده از StrictAndMessageFilter دو فیلتر مورد نظر را با هم ترکیب می‌کند.
  • Custom : می‌توان فیلتر مورد نظر را تعریف کرده و این جا فراخوانی نمایید.
  • MatchAll : با استفاده از MatchAllMessageFilter تمام فیلتر‌ها بررسی خواهند شد.
  • EndpointAddress : برای فیلتر ادرس درخواست‌های با استفاده از EndpointAddressMessageFilter مورد استفاده قرار می‌گیرد.
  • EndpointName : فیلتر  با استفاده EndpointNameMessageFilter بر روی نام Endpoint سرویس مورد نظر انجام می‌گیرد.

FilterData برای تعیین مقادیر مورد نیاز برای FilterType مورد استفاده قرار می‌گیرد.

برای مثال:

<filters>
     <filter name="EndpointNameFilter" filterType="EndpointName" 
             filterData="calculatorEndpoint"/>  
     <filter name="RoundRobinFilter1" filterType="Custom" 
             customType="RoutingServiceFilters.RoundRobinMessageFilter, 
             RoutingService" filterData="group1"/>
     <filter name="RoundRobinFilter2" filterType="Custom" 
             customType="RoutingServiceFilters.RoundRobinMessageFilter, 
             RoutingService" filterData="group1"/>
</filters>
Filter Table
  در واقع مجموعه ای است از اشیای تعریف شده از نوع FilterTableEntryElement که  ارتباط را بین یک فیلتر و مقصد (Endpoint) تعیین می‌نماید. هم چنین امکان تعریف اولویت برای هرکدام از مقصد‌ها یا Endpoint‌ها وجود دارد.
یک مثال:
<routing>
     <filters>
       <filter name="AddAction" filterType="Action" filterData=”Add” />
       <filter name="SubtractAction" filterType="Action" filterData=”Subtract” />
     </filters>
     <filterTables>
       <table name="routingTable1">
         <filters>
           <add filterName="AddAction" endpointName="Addition" />
           <add filterName="SubtractAction" endpointName="Subtraction" />
         </filters>
       </table>
     </filterTables>    
</routing>

می‌توان برای فیلتر‌ها اولویت تعیین کرد. این کار از طریق تنظیم خاصیت Priority امکان پذیر است. در صورت عدم تعیین Prioirty مقدار پیش فرض صفر خواهد بود.
<filterTables>
     <filterTable name="filterTable1">      
          <add filterName="EndpointNameFilter" endpointName="regularCalcEndpoint" 
               priority="1"/>        
          <add filterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint" 
               priority="0"/>
     </filterTable>
</filterTables>
در مثال بالا برای یک endpointName مشترک دو فیلتر نوشته شده است با اولویت‌های متفاوت. دو صورتی که اولویت‌ها یکسان باشد با توجه به ترتیب تعریف در filterTable، فیلتر‌ها اعمال خواهند شد.
تهیه BackupList
BackupList‌ها این امکانی را در اختیار ما قرار خواهند داد که بتوانیم در صورت عدم موفقیت در عملیات مسیر یابی (برای مثال وقوع CommunicationException) لیستی از مسیر‌های جایگزین را تعیین نماییم. در صورت وقوع هر گونه خطا در هنگام فراخوانی سرویس، به جای مواجه شدن با یک استثنا، عملیات مسیر یابی به صورت خودکار به endpoint‌های تعیین شده در BackupList منتقل خواهد شد.
<filterTables>
     <filterTable name="filterTable1">
          <add filterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>
     </filterTable>
</filterTables>
<backupLists>
     <backupList name="backupEndpointList">
          <add endpointName="backupServiceQueue" />
          <add endpointName="alternateServiceQueue" />
     </backupList>
</backupLists>
در مثال بالا دو endpoint در لیست backup قرار دارد. در صورت وقوع استثنا در Destination عملیات  ابتدا به backupServiceQueue منتقل می‌شود و اگر باز هم خطایی وجود داشت نوبت به alternateServiceQueue خواهد رسید.
اشتراک‌ها
ساخت اپلیکیشن های لوکال با ASP.NET Core تحت HTTPS, SSL, و Self-Signed Certs

You want your local web development set up to reflect your production reality as much as possible. URL parsing, routing, redirects, avoiding mixed-content warnings, etc. It's very easy to accidentally find oneself on http:// when everything in 2018 should be under https://.

I'm using ASP.NET Core 2.1 which makes local SSL super easy. After installing from http://dot.net I'll "dotnet new razor" in an empty folder to make a quick web app. 

ساخت اپلیکیشن های لوکال با ASP.NET Core تحت HTTPS, SSL, و Self-Signed Certs
مطالب
کامپوننت‌ها در AngularJS 1.5
در نسخه‌های  AngularJS 1.x عموماً با کمک کنترلرها و دایرکتیوها، می‌توانیم ویژگی‌های جدیدی را به اپلیکیشن‌هایمان اضافه کنیم؛ از دایرکتیوها برای ایجاد عناصر سفارشی HTML می‌توانستیم (می‌توانیم) استفاده کنیم. مشکل دایرکتیوها این است که برای ایجاد یک عنصر سفارشی ساده باید تنظیمات زیادی را انجام دهیم. در نسخه‌ی AngularJS 1.5 یک API جدید با نام کامپوننت معرفی شده است و این قابلیت، مدل ساده‌ی برنامه‌نویسی در کنترلرها و همچنین قدرت دایرکتیوها را در اختیارمان قرار خواهد داد. سینتکس این API خیلی شبیه به استفاده از کامپوننت‌ها در Angular 2.0 است. این یک مزیت مهم محسوب می‌شود؛ زیرا امکان مهاجرت از نسخه‌ی 1.5 به نسخه‌ی 2 را خیلی ساده خواهد کرد.

نحوه‌ی تعریف یک کامپوننت در AngularJS 1.5
همانند کنترلر و دایرکتیو، برای تعریف یک کامپوننت نیز باید از module API استفاده کنیم:

بنابراین برای ایجاد یک کامپوننت می‌توانیم به اینصورت عمل کنیم:

var app = angular.module("dntModule", []);
app.component("pmApp", {
  template: `Hello this is a simple component`
});

همانطور که مشاهده می‌کنید تابع component دو پارامتر را از ورودی دریافت خواهد کرد؛ نام کامپوننت و یک شیء برای تعیین تنظیمات کامپوننت. نام کامپوننت در اینجا به صورت camel case تعریف شده است؛ که در واقع یک convention برای Angular است. در این‌حالت برای استفاده‌ی از کامپوننت باید به اینصورت عمل کنیم:

<pm-app></pm-app>

در قسمت تنظیمات کامپوننت، در ساده‌ترین حالت یک template تعیین شده‌است که بیانگر نحوه‌ی رندر شدن یک کامپوننت می‌باشد. در اینحالت وقتی انگیولار به تگ فوق برسد، یک کامپوننت با نام pmApp را بارگذاری خواهد کرد.


ایجاد یک کامپوننت ساده

در ادامه می‌خواهیم یک کامپوننت ساده را جهت نمایش یکسری URL درون صفحه طراحی کنیم. ساختار صفحه index.html به صورت زیر خواهد بود:

<html ng-app="DNT">
<head>
    <meta charset="UTF-8">
    <title>Using Angular Component</title>
    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
    <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css">
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-3">
                <dnt-widget></dnt-widget>
            </div>
        </div>
    </div>
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>
    <script src="scripts/components/dnt-widget.component.js"></script>
</body>
</html>

در اینجا ابتدا توسط دایرکتیو ng-app، به Angular، ماژول‌مان را معرفی کرده‌ایم. سپس مداخل بوت‌استرپ و کتابخانه‌ی font-awesome را مشاهده می‌کنید. در ادامه، کتابخانه‌ی Angular و همچنین فایل app.js جهت معرفی ماژول برنامه معرفی شده‌است. در نهایت نیز یک فایل در مسیر ذکر شده برای قرار دادن کدهای کامپوننت در مسیر scripts/components اضافه شده‌است.

همانطور که ملاحظه می‌کنید، کامپوننت‌مان به صورت یک تگ سفارشی، درون صفحه قرار گرفته است:

<dnt-archive></dnt-archive>

در ادامه باید به Angular، نحوه‌ی تعریف این کامپوننت را اعلام کنیم. بنابراین یک فایل جاوا اسکریپتی را با نام dnt-widget.component، با محتویات زیر ایجاد کنید:

(function () {    
    "use strict";    
    var app = angular.module("DNT");    
    function DntArchiveController() {
      var model = this;      
      model.panel = {
          title: "Panel Title",
          items: [
              {
                  title: "Dotnettips", url: "https://www.dntips.ir"
              },
              {
                  title: "Google", url: "http://www.google.con"
              },
              {
                  title: "Yahoo", url: "http://www.yahoo.con"
              }
          ]
      };  
    };
    
    app.component("dntWidget", {
        templateUrl: '/scripts/components/dnt-widget.component.html',
        controllerAs: "model",
        controller: DntArchiveController
    });
} ());

توضیح کدهای فوق:

همانطور که مشاهده می‌کنید، برای پارمتر دوم کامپوننت، سه پراپرتی را تعیین کرده‌ایم:

templateUrl: به کمک این پراپرتی به Angular گفته‌ایم که محتوای قالب این کامپوننت، درون یک فایل HTML مجزا قرار دارد و به صورت linked template می‌باشد.

controllerAs: یکی از مزایای استفاده از کامپوننت‌ها، استفاده از controller as syntax می‌باشد. لازم به ذکر است اگر این پراپرتی را مقداردهی نکنیم، به صورت پیش‌فرض مقدار ctrl$ در نظر گرفته خواهد شد.

controller: مزیت دیگر کامپوننت‌ها، استفاده از کنترلرها است. با استفاده از این پراپرتی، یک کنترلر را برای کامپوننت‌مان رجیستر کرده‌ایم. در نتیجه زمانیکه‌ی Angular می‌خواهد کامپوننت‌مان را نمایش دهد، تابع تعریف شده برای این پراپرتی، جهت ایجاد یک controller instance فراخوانی خواهد شد. بنابراین هر پراپرتی یا تابعی که برای این controller instance تعریف کنیم، به راحتی درون ویوی آن جهت اعمال بایندینگ در دسترس خواهد بود (در نتیجه نیازی به scope$ نخواهد بود).

درون کنترلر نیز برای راحتی کار و همچنین به عنوان یک best practice، مقدار this را توسط یک متغیر با نام model، کپچر کرده‌ایم. در اینجا یک شیء را با نام panel نیز به مدل اضافه کرده‌ایم.


محتویات تمپلیت:

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">
            <span class="fa fa-archive"></span>
            {{ model.panel.title}}
        </h3>
    </div>
    <ul class="list-group">
        <li class="list-group-item" ng-repeat="item in model.panel.items">
            <span class="fa fa-industry"></span>
            <a href="{{ item.url }}">{{ item.title }}</a>
        </li>
    </ul>
</div>

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



همانطور که مشاهده می‌کنید استفاده از کامپوننت‌ها در Angular 1.5 در مقایسه با ایجاد دایرکتیوها و کنترلر‌ها خیلی ساده‌تر است. در واقع امکانات این API جدید تنها به مثال فوق ختم نمی‌شود؛ بلکه این API یک سیستم مسیریابی جدید را نیز معرفی کرده است که در قسمت‌های بعدی به آن نیز خواهیم پرداخت.


جهت تکمیل بحث نیز یک تقویم شمسی ساده را در اینجا قرار داده‌ام. می‌توانید جهت مرور بحث جاری به کدهای آن مراجعه کنید. البته هدف از تعریف این پروژه تنها یک مثال ساده برای معرفی کامپوننت‌ها بود و طبیعتاً باگ‌های زیادی دارد. اگر مایل بودید می‌توانید در توسعه‌ی آن مشارکت نمائید.


کدهای این قسمت را نیز از اینجا می‌توانید دریافت کنید.

اشتراک‌ها
آموزش Asp.Net Core Web API CRUD با Angular 16

Asp.Net Core Web API CRUD with Angular 16
In this .Net 7 tutorial, we have implemented CRUD operations in asp.net core web api with angular 16 using entity framework core and SQL server. 

آموزش Asp.Net Core Web API CRUD با Angular 16
اشتراک‌ها
Angular 3 به زودی منتشر خواهد شد

Expected in March , Angular 3 will focus on improved tooling and a reduction in generated code, said Rob Wormald, of the Angular core team and a developer advocate at Google.  

Angular 3 به زودی منتشر خواهد شد
نظرات مطالب
انتقال دائمی آدرس ها (Permanent Ridirect) در ASP.NET Webform
سلام؛ این کار رو انجام دادم ولی همچنان برای هر صفحه، دو آدرس دارم؛ یکی آدرس اصلی بدون پسوند aspx و یکی آدرسی که روت کردم. در واقع friendlyurls و routing هر کدام جدا کار خودشون رو انجام میدن .
نظرات مطالب
یک نکته درباره Angular routeProvider
تمام مواردی که در routing مربوط به angularjs هستش در ui-router هم وجود دارد و مواردی مثل nested views و  multiple named views بهش اضافه شده و عملا در پروژه‌ها کاربردی‌تر خواهد بود.