Along with NativeScript 3.4 we also released a new version of the nativescript-angular plugin with official support for Angular 5. The update includes support for Angular’s new AnimationBuilder APIs, as well as some iOS-specific startup time improvements. You can learn more about these changes in the nativescript-angular changelog.
اشتراکها
Angular v16 منتشر شد
اشتراکها
Angular 6 منتشر شد
اشتراکها
پلاگین angular-confirm
نظرات مطالب
React 16x - قسمت 1 - معرفی و شروع به کار
Framework | Mobile URLs | Desktop URLs |
---|---|---|
jQuery | 4,615,474 | 3,714,643 |
React | 489,827 | 241,023 |
Vue.js | 85,649 | 43,691 |
Angular | 19,423 | 18,088 |
نکات ارتقاء به نگارش RTM
همان «نکات ارتقاء به نگارش RC5 » در اینجا هم برقرار هستند. فقط نام فایل app.routes.ts به app.routing.ts تغییر یافتهاست.
تغییرات پروژه را در اینجا میتوانید دنبال کنید.
چند مطلب تکمیلی
Using the New Release of Angular 2’s Router 3.0.0
Angular 2 Routing With Modules
همان «نکات ارتقاء به نگارش RC5 » در اینجا هم برقرار هستند. فقط نام فایل app.routes.ts به app.routing.ts تغییر یافتهاست.
تغییرات پروژه را در اینجا میتوانید دنبال کنید.
چند مطلب تکمیلی
Using the New Release of Angular 2’s Router 3.0.0
Angular 2 Routing With Modules
قسمت قبل به IIS7 اختصاص داشت که شاید برای خیلیها کاربرد نداشته باشد خصوصا اینکه برنامه نویسها ترجیح میدهند به روشهایی روی بیاورند که کمتر نیاز به دخالت مدیر سرور داشته باشد؛ یا زمانیکه سایت شما بر روی یک هاست اینترنتی قرار گرفته است عملا شاید دسترسی خاصی به تنظیمات IIS نداشته باشید (مگر اینکه یک هاست اختصاصی را تهیه کنید).
برای IIS6 و ماقبل از آن و حتی بعد از آن!، حداقل دو روش برای کش کردن اطلاعات استاتیک وجود دارد:
الف) استفاده از web resources معرفی شده در ASP.Net 2.0 به بعد
در مورد نحوهی تعریف و بکارگیری web resources میتوان به مقاله "تبدیل پلاگینهای jQuery به کنترلهای ASP.Net" رجوع کرد.
همانطور که در شکل فوق نیز ملاحظه میکنید، هدر مربوط به مدت زمان منقضی شدن کش سمت کلاینت یک web resource توسط موتور ASP.Net به صورت خودکار به سال 2010 تنظیم شده است و این مقدار خالی نیست.
ب) افزودن این هدر به صورت دستی
برای این منظور باید در نحوهی ارائه فایلهای استاتیک دخالت کنیم و اینکار را با استفاده از یک generic handler میتوان انجام داد.
کد این generic handler میتواند به صورت زیر باشد:
using System;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Reflection;
namespace test1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class cache : IHttpHandler
{
private static void cacheIt(TimeSpan duration)
{
HttpCachePolicy cache = HttpContext.Current.Response.Cache;
FieldInfo maxAgeField = cache.GetType().GetField("_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
maxAgeField.SetValue(cache, duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(duration));
cache.SetMaxAge(duration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
public void ProcessRequest(HttpContext context)
{
string file = context.Request.QueryString["file"];
if (string.IsNullOrEmpty(file))
{
return;
}
string contetType = context.Request.QueryString["contetType"];
if (string.IsNullOrEmpty(contetType))
{
return;
}
context.Response.Write(File.ReadAllText(context.Server.MapPath(file)));
//Set the content type
context.Response.ContentType = contetType;
// Cache the resource for 30 Days
cacheIt(TimeSpan.FromDays(30));
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
این generic handler دو کوئری استرینگ را دریافت میکند؛ file جهت دریافت نام فایل و contetType جهت مشخص سازی نوع محتوایی که باید سرو شود؛ مثلا جاوا اسکریپت یا استایل شیت و امثال آن. سپس زمانیکه محتوا را Response.Write میکند، هدر مربوط به کش شدن آنرا نیز به 30 روز تنظیم مینماید.
تابع مربوط به کش کردن اطلاعات از مقاله ASP.NET Ajax Under-the-hood Secrets استخراج شد.
روش استفاده در مورد فایلهای CSS
بجای تعریف یک فایل CSS در صفحه، به صورت استاندارد، اکنون تعریف متداول را به صورت زیر اصلاح کنید:
<link type="text/css" href="cache.ashx?v=1&file=site.css&contetType=text/css" rel="Stylesheet" />
روش استفاده در مورد فایلهای JS
<script type="text/javascript" src="cache.ashx?v=1&file=js/jquery-1.3.2.min.js&contetType=application/x-javascript"></script>
در قسمت قبل، ساختار فرم ثبت اطلاعات کارمندان را تکمیل کردیم. در این قسمت قصد داریم این اطلاعات را در کامپوننت آن توسط data binding دریافت کنیم.
نقش ngModel در data binding
ngModel دایرکتیوی است که وجود آن سبب میشود تا Angular آن المان ورودی خاص را تحت نظر قرار دهد:
در حالت تعریفی فوق، هیچگونه عملیات data binding ایی صورت نمیگیرد؛ اما Angular به علت وجود ngModel، از وجود این فیلد مطلع شدهاست. اما کامپوننت برنامه اطلاعات خاصی را دریافت نخواهد کرد.
برای رفع این مشکل میتوان با data binding یک طرفه شروع کرد:
در اینجا از syntax ویژهی property binding استفاده شده و ngModel داخل [] قرار گرفتهاست و به firstName تنظیم شدهاست. در این حالت Angular در کامپوننت متناظر با این قالب HTML ایی، به دنبال یک خاصیت عمومی به نام firstName میگردد و مقدار اولیهی این فیلد را از آن دریافت میکند.
در حالت data binding یک طرفه، اگر کاربر اطلاعات فیلد firstname را در فرم برنامه تغییر دهد، این اطلاعات به خاصیت عمومی firstName منعکس نخواهد شد.
برای رفع این مشکل (در صورت نیاز)، میتوان از data binding دو طرفه استفاده کرد:
این حالت شبیه به حالت data binding یک طرفه است؛ با این تفاوت که رویدادگردانی ngModelChange نیز به آن اضافه شدهاست. در اینجا event$ به مقدار فیلد تغییر یافته اشاره میکند و آنرا به firstName انتساب میدهد.
البته این حالت دو طرفه، syntax ساده شدهی زیر را که به banana in the box نیز معروف شدهاست (موز همان () است و جعبه به [] اشاره میکند)، نیز میتواند داشته باشد که بیشتر مورد استفاده قرار میگیرد:
تعریف مدل فرم ثبت اطلاعات کارمندان
برای نگهداری اطلاعات فرم کارمندان، کلاس Employee را به ماژول Employee اضافه میکنیم:
با این خروجی:
سپس ساختار این کلاس را به نحو ذیل تکمیل خواهیم کرد که هر کدام از خواص آن، معادل یکی از المانهای فرم است:
TypeScript این امکان را میدهد تا بتوان خواص عمومی را مستقیما در سازندهی کلاس تعریف کرد. بنابراین در اینجا برای نمونه firstName هم یکی از آرگومانهای سازندهی کلاس کارمند است و هم یک خاصیت عمومی تعریف شدهی در آن. به علاوه در اینجا میتوان به این خواص، مقادیر پیش فرضی را نیز انتساب داد تا در حین وهله سازی آن بتوان از تعریف اجباری یک سری از پارامترها صرفنظر کرد.
پس از آن، به فایل employee-register.component.ts مراجعه کرده و وهلهای از کلاس را به صورت یک خاصیت عمومی در اختیار قالب HTML ایی آن که فرم جاری را تشکیل میدهد، قرار میدهیم:
ابتدا کلاس کارمند import شده و سپس وهلهای از آن به نام model، به صورت یک خاصیت عمومی در اختیار قالب آن قرار گرفتهاست.
تغییر قالب فرم ثبت اطلاعات کارمندان برای اتصال به model
در ادامه، مرحله به مرحله قالب فرم جاری را جهت اتصال به شیء model فوق تغییر خواهیم داد:
اتصال به Text boxes
همانطور که مشاهده میکنید، اینبار ngModel خالی قسمت قبل را توسط syntax تکمیلی banana in the box به data binding دو طرفه تغییر دادهایم. به این ترتیب در ابتدای نمایش فرم، این دو فیلد، مقادیر اولیه نام و نام خانوادگی را از شیء model دریافت کرده و نمایش میدهند. به علاوه اگر فرم نیز تغییر کند، این اطلاعات به شیء model و خواص آن نیز منعکس میشوند.
برای بررسی این مورد، در پایان فرم جهت دیباگ data binding، اطلاعاتی را که در مدل داریم و همچنین اطلاعاتی را که Angular در حال نظارت بر آنها است، به صورت json در صفحه درج میکنیم:
برای مثال یکبار [()] را به [] تبدیل کنید و سپس سعی در تغییر مقادیر فرم نمائید. مشاهده میکنید هرچند این اطلاعات تحت نظارت Angular هستند، اما چون data binding به حالت یک طرفه تغییر کردهاست، دیگر انعکاس آنها، در Model مشاهده نمیشوند.
اتصال به Check boxes
روش کار در اینجا نیز همانند قبل است. با استفاده از data binding دو طرفه، مقدار checkbox را به یک خاصیت عمومی boolean انتساب دادهایم و برعکس (زمانیکه فرم برای بار اول نمایش داده میشود، مقدار اولیهی خود را از شیء model دریافت میکند).
اتصال به Radio buttons
روش اتصال به radio buttons نیز بر اساس data binding دو طرفهاست. فقط در اینجا دقیقا یک خاصیت مشخص، به چندین radio button متصل شدهاست و در نهایت در این گروه که بر اساس name هایی یکسان تشکیل شدهاست، یک مقدار انتخاب میشود و مقدار آن از ویژگی value المان متناظر دریافت میگردد.
اتصال به Drop downs
در اینجا نیز ابتدا نامی به این المان انتساب داده شدهاست و سپس توسط data binding دو طرفه، خاصیت متناظری از مدل را به این المان متصل کردهایم یا برعکس؛ زمانیکه این فرم برای اولین بار نمایش داده میشود، مقدار اولیهی این فیلد بر اساس مقدار آن در شیء model تعیین میشود:
نحوهی فراخوانی یک متد در حین data binding دو طرفه
همانطور که در ابتدای بحث نیز عنوان شد، data binding دو طرفه را به نحو دیگری نیز میتوان تعریف کرد:
در اینجا بجای استفادهی از syntax معروف banana in the box، از روش اتصال یک طرفه و سپس دریافت تغییرات از طریق یک رخدادگردان استفاده شدهاست. مزیت این روش امکان دسترسی همزمان به مقدار وارد شدهی توسط کاربر، در کامپوننت متناظر میباشد:
برای مثال در اینجا اگر کاربر حرف اول یک نام را با حروف کوچک وارد کند، توسط این متد به حرف بزرگ تبدیل شده و جایگزین میشود. این جایگزینی نیز بلافاصله در فرم منعکس خواهد شد.
در قسمت بعد مباحث اعتبارسنجی فرمهای مبتنی بر قالبها را بررسی میکنیم.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: angular-template-driven-forms-lab-03.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کردهاید. سپس از طریق خط فرمان به ریشهی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگیهای آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
نقش ngModel در data binding
ngModel دایرکتیوی است که وجود آن سبب میشود تا Angular آن المان ورودی خاص را تحت نظر قرار دهد:
<!--no binding --> <input name="firstname" ngModel>
برای رفع این مشکل میتوان با data binding یک طرفه شروع کرد:
<!--one way binding --> <input name="firstname" [ngModel]="firstName">
در حالت data binding یک طرفه، اگر کاربر اطلاعات فیلد firstname را در فرم برنامه تغییر دهد، این اطلاعات به خاصیت عمومی firstName منعکس نخواهد شد.
برای رفع این مشکل (در صورت نیاز)، میتوان از data binding دو طرفه استفاده کرد:
<!--two way binding --> <input name="firstname" [ngModel]="firstName" (ngModelChange)="firstName=$event">
البته این حالت دو طرفه، syntax ساده شدهی زیر را که به banana in the box نیز معروف شدهاست (موز همان () است و جعبه به [] اشاره میکند)، نیز میتواند داشته باشد که بیشتر مورد استفاده قرار میگیرد:
<!--two way binding --> <input name="firstname" [(ngModel)]="firstName">
تعریف مدل فرم ثبت اطلاعات کارمندان
برای نگهداری اطلاعات فرم کارمندان، کلاس Employee را به ماژول Employee اضافه میکنیم:
> ng g cl Employee/Employee
installing class create src\app\Employee\employee.ts
export class Employee { constructor( public firstName: string, public lastName: string, public isFullTime: boolean, public paymentType: string, public primaryLanguage: string ) {} }
پس از آن، به فایل employee-register.component.ts مراجعه کرده و وهلهای از کلاس را به صورت یک خاصیت عمومی در اختیار قالب HTML ایی آن که فرم جاری را تشکیل میدهد، قرار میدهیم:
import { Employee } from "app/employee/employee"; export class EmployeeRegisterComponent implements OnInit { languages = ["Persian", "English", "Spanish", "Other"]; model = new Employee("Vahid", "N", true, "FullTime", "Persian");
تغییر قالب فرم ثبت اطلاعات کارمندان برای اتصال به model
در ادامه، مرحله به مرحله قالب فرم جاری را جهت اتصال به شیء model فوق تغییر خواهیم داد:
اتصال به Text boxes
<form #form="ngForm" novalidate> <div class="form-group"> <label>First Name</label> <input type="text" class="form-control" name="firstName" [(ngModel)]="model.firstName"> </div> <div class="form-group"> <label>Last Name</label> <input type="text" class="form-control" name="lastName" [(ngModel)]="model.lastName"> </div>
برای بررسی این مورد، در پایان فرم جهت دیباگ data binding، اطلاعاتی را که در مدل داریم و همچنین اطلاعاتی را که Angular در حال نظارت بر آنها است، به صورت json در صفحه درج میکنیم:
<button class="btn btn-primary" type="submit">Ok</button> </form> Model: {{ model | json }} <br> Angular: {{ form.value | json }} <br> form.pristine: {{ form.pristine }}
اتصال به Check boxes
<div class="checkbox"> <label> <input type="checkbox" name="is-full-time" [(ngModel)]="model.isFullTime"> Full Time Employee </label> </div>
اتصال به Radio buttons
<label>Payment Type</label> <div class="radio"> <label> <input type="radio" name="paymentType" value="FullTime" checked [(ngModel)]="model.paymentType"> Full Time </label> </div> <div class="radio"> <label> <input type="radio" name="paymentType" value="PartTime" [(ngModel)]="model.paymentType"> Part Time </label> </div>
اتصال به Drop downs
<div class="form-group"> <label>Primary Language</label> <select class="form-control" name="primaryLanguage" [(ngModel)]="model.primaryLanguage"> <option *ngFor="let lang of languages"> {{ lang }} </option> </select> </div>
نحوهی فراخوانی یک متد در حین data binding دو طرفه
همانطور که در ابتدای بحث نیز عنوان شد، data binding دو طرفه را به نحو دیگری نیز میتوان تعریف کرد:
<div class="form-group"> <label>First Name</label> <input type="text" class="form-control" name="firstName" [ngModel]="model.firstName" (ngModelChange)="firstNameToUpperCase($event)"> </div>
firstNameToUpperCase(value: string) { if (value.length > 0) this.model.firstName = value.charAt(0).toUpperCase() + value.slice(1); else this.model.firstName = value; }
در قسمت بعد مباحث اعتبارسنجی فرمهای مبتنی بر قالبها را بررسی میکنیم.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: angular-template-driven-forms-lab-03.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کردهاید. سپس از طریق خط فرمان به ریشهی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگیهای آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.