مشخصات مقاله
-
1026
-
0.0
-
3662
-
0
-
0
نحوه تعریف کامپوننت ها در Angular
معرفی کامپوننت ها
کامپوننت ها بخش کوچکی از صفحه به نام view را کنترل میکنند. برای مثال تک تک کامپوننت ها هر یک از view های زیر را در این آموزش کنترل و تعریف میکنند:
- ریشهی برنامه به همراه لینکهای گشت و گذار
- لیست هیروها
- ویرایشگر هیرو
شما به جای یک کلاس، منطق برنامهی یک کامپوننت (کاری که این کامپوننت انجام میدهد تا از view پشتیبانی کند) را تعریف میکنید. این کلاس از طریق API ویژگیها و متدها با این view تعامل برقرار میکند.
برای مثال HeroListComponent ویژگی heroes را دارد که این ویژگی، آرایهای از هیروها را در خود نگه میدارد. متد selectHero() آن، زمانی که کاربر برای انتخاب یک هیرو از این لیست بر روی یک هیرو کلیک میکند، ویژگی selectedHero را تنظیم میکند. این کامپوننت هیروها را از یک سرویس دریافت میکند. این سرویس یک ویژگی پارامتری تایپ اسکریپت در constructor است. این سرویس از طریق سیستم تزریق وابستگی در اختیار کامپوننت قرار میگیرد.
src/app/hero-list.component.ts (class)
export class HeroListComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private service: HeroService) { }
ngOnInit() {
this.heroes = this.service.getHeroes();
}
selectHero(hero: Hero) { this.selectedHero = hero; }
}
هم زمان با حرکت کاربر در برنامه Angular کامپوننت ها را ایجاد، به روز رسانی و نابود میکند. میتوانید از طریق هوک های چرخهی عمر اختیاری مانند ngOnInit() در هر یک از این لحظات اقدام به کاری بکنید.
متادیتای کامپوننت
دکوراتور @Component درست در پایین خود کلاس را به صورت یک کلاس کامپوننت تعیین و متادیتاهای آن را مشخص میکند. در نمونه کد زیر میتوانید مشاهده کنید که HeroListComponent صرفاً یک کلاس است و در آن هیچ سینتکس و یا علامت گذاری خاصی استفاده نشده است. تا زمانی که با استفاده از دکوراتور @Component آن را به عنوان یک کامپوننت نشان نکنید، به یک کامپوننت تبدیل نخواهد شد.
متادیتای یک کامپوننت به Angular میگوید که کجا میتواند بلوکهای ساختاری اصلی مورد نیاز خود را برای ایجاد و ارائهی این کامپوننت و view آن دریافت کند. این متادیتا قالبی را به کامپوننت مرتبط میکند. این کار یا به صورت مستقیم از طریق کد و یا با ارجاع انجام میشود. کامپوننت وقالب آن در کنار یکدیگر یک view را توصیف میکنند.
متادیتای @Component علاوه بر نگه داشتن یا اشاره به قالب، برای مثال، چگونگی اشاره به کامپوننت در HTML و سرویسهای مورد نیاز آن را نیز پیکربندی میکند. در ادامه مثالی از یک متادیتای ابتدایی مربوط به HeroListComponent را مشاهده میکنید.
src/app/hero-list.component.ts (metadata)
@Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
providers: [HeroService]
})
export class HeroListComponent implements OnInit {
/*... */
}
این مثال برخی از مفیدترین گزینههای پیکربندی @Component را نشان میدهد:
- Selector: یک انتخاب گر CSS است که به Angular میگوید نمونهای از این کامپوننت را در هر مکانی که تگ متناظر را در HTML قالب پیدا میکند، ایجاد و درج کند. برای مثال اگر HTML برنامهای شامل < /app-hero-list > باشد، در این صورت Angular نمونهای از ویوی HeroListComponent را بین این تگها درج میکند.
- TemplateUrl: آدرس مرتبط با ماژول قالب HTML این کامپوننت. به عنوان جایگزین میتوانید قالب HTML را به عنوان مقداری از ویژگی template فراهم کنید. این قالب host view این کامپوننت را تعریف میکند.
- Providers: آرایهای از ارائه کنندههای سرویسهایی است که کامپوننت به آن نیاز دارد. در این مثال این ارائه دهندهها به Angular می گویند چگونه نمونهی HeroService که constructor کامپوننت برای دریافت لیست هیروها و نمایش آنها استفاده میکند را فراهم کند.
شما view کامپوننت با قالب همراه آن را تعریف میکنید. قالبها شکلی از HTML هستند که به Angular می گویند چگونه کامپوننت را رندر کند.
View ها معمولاً به صورت سلسله مراتبی در کنار یکدیگر قرار میگیرند. با استفاده از این قابلیت میتوانید به صورت یک واحد، کل بخشها یا صفحات رابط کاربری را آشکار و یا مخفی کنید. قالبی که بلافاصله به یک کامپوننت ارتباط داده شده است، host view این کامپوننت را تعریف میکند. کامپوننت میتواند یک سلسله مراتب view را نیز ایجاد کند که این سلسله مراتب شامل view های ادغام شده هستند و توسط کامپوننت های دیگر میزبانی میشوند.
این سلسله مراتب میتواند شامل view های کامپوننت های موجود در NgModule یکسانی باشد، البته این سلسله مراتب میتواند شامل view های کامپوننت هایی که در NgModule های مختلف تعریف شدهاند نیز باشد (معمولاً همین طور هم هست).
سینتکس قالب
قالبها شبیه به HTML معمولی هستند؛ با این تفاوت که آنها سینتکس قالب Angular را نیز در خود جای دادهاند. این سینتکس بر اساس منطق برنامهی شما و حالت برنامه، همچنین دادههای DOM، HTML را تغییر میدهد. قالب شما میتواند از مقیدسازی دادهها برای هماهنگ کردن برنامه و دادههای DOM، از پایپها برای تبدیل دادهها قبل از نمایش و از دستورالعملها برای به کارگیری منطق برنامه در چیزی که نمایش داده میشود، استفاده کند.
برای مثال، در ادامه میتوانید قالبی را برای HeroListComponent بخش آموزش مشاهده کنید.
src/app/hero-list.component.html
< h2 >Hero List< /h2 >
< p >< i >Pick a hero from the list< /i >< /p >
< ul >
< li *ngFor="let hero of heroes" (click)="selectHero(hero)" >
{ {hero.name} }
< /li >
< /ul >
< app-hero-detail *ngIf="selectedHero" [hero]="selectedHero" >< /app-hero-detail >
این قالب از عناصر HTML رایجی مانند < h2 > و < p >استفاده میکند. همچنین عناصر سینتکس قالب Angular *ngFor, { {hero.name} }, (click), [hero] و < app-hero-detail > را شامل میشود. عناصر سینتکس قالب به Angular میگوید که چگونه HTML را با استفاده از منطق و دادههای برنامه در صفحه رندر کند.
- دستورالعمل *ngFor به Angular میگوید که در لیستی به صورت حلقهای به تکرار بپردازد.
- { {hero.name}}, (click) و [hero] دادههای برنامه را در DOM و از آن مقید میکنند و به ورودی کاربر پاسخ میدهند. برای اطلاعات بیشتر به بخش مقیدسازی دادهها که در زیر آمده است مراجعه کنید.
- تگ < app-hero-detail > در این مثال عنصری است که بیانگر کامپوننت جدید HeroDetailComponent است. این کامپوننت (که کد آن نشان داده نشده است) view فرزند hero-detail مربوط به HeroListComponent را تعریف میکند. توجه کنید که چگونه کامپوننت های اختصاصی مانند این کامپوننت میتوانند بدون هیچ نقصی و در آرایش یکسانی با HTML بومی ترکیب شوند.
مقیدسازی دادهها
بدون چهارچوب، این شما هستید که باید مقادیر دادهای را به کنترلهای HTML ارسال کنید، پاسخهای کاربر را عملی کنید و مقادیر را به روز رسانی کنید. همان طور که تمامی برنامه نویسان باتجربهی جی کوئری گواه این مطلب هستند، نوشتن چنین منطقهای دریافتی و ارسالی به صورت دستی کاری خسته کننده، پرخطا و کاملاً ناخوانا است.
Angular از مقیدسازی دوطرفهی دادهها پشتیبانی میکند. این نوع از مقیدسازی، سازوکاری برای هماهنگ سازی بخشهای یک قالب با بخشهای یک کامپوننت است. برای آن که Angular درک کند چگونه هر دو طرف را به یکدیگر متصل کند، markup مقیدسازی را به HTML قالب اضافه کنید.
در دیاگرام زیر چهار نوع از markup مقیدسازی داده نشان داده شده است. مسیر هر یک از آنها میتواند از DOM، به DOM و یا دوطرفه باشد.
در مثال مربوط به قالب HeroListComponent از سه نوع مقیدسازی داده استفاد شده است.
src/app/hero-list.component.html (binding)
< li >{ {hero.name}}< /li >
< app-hero-detail [hero]="selectedHero" >< /app-hero-detail >
< li (click)="selectHero(hero)" >< /li >
- اینترپولاسیون { {hero.name}}، مقدار ویژگی hero.name کامپوننت را داخل عنصر < li > نمایش میدهد.
- مقیدسازی ویژگی [hero] مقدار selectedHero را از HeroListComponent مادر به ویژگی hero مربوط به HeroDetailComponent فرزند میدهد.
- مقیدسازی رویداد (click)، زمانی که کاربر بر روی اسم هیرویی کلیک میکند، متد selectHero کامپوننت را فراخوانی میکند.
مقیدسازی دوطرفهی داده (که معمولاً در اشکال قالب محور کاربرد دارند) در تنها یک علامت گذاری، ویژگی و مقیدسازی رویداد را با یکدیگر ترکیب میکند. در اینجا میتوانید مثالی از قالب HeroDetailComponent را مشاهده کنید. در این مثال از مقیدسازی دوطرفهی داده به همراه دستورالعمل ngModel استفاده شده است.
src/app/hero-detail.component.html (ngModel) < input [(ngModel)]="hero.name" >
در مقیدسازیهای دوطرفه، مقدار ویژگی داده درست مانند مقیدسازی ویژگی از کامپوننت به سمت کادر ورودی حرکت میکند. تغییرات کاربر مانند مقیدسازی رویداد به کامپوننت برگشت داده میشوند و ویژگی را بر روی آخرین مقدار تنظیم میکنند.
Angular از ریشهی درخت کامپوننت برنامه از طریق تمامی کامپوننت های فرزند، تمامی مقیدسازیهای دادهها را یک بار به ازای هر چرخهی رویداد جاوا اسکریپت پردازش میکند.
مقیدسازی داده در برقرار ارتباط بین قالب و کامپوننت آن نقش مهمی را ایفا میکند؛ همچنین در برقراری ارتباط بین کامپوننت های فرزند و مادر نیز این مقیدسازی حائز اهمیت است.
پایپها
با کمک پایپها میتوانید در Angular داخل HTML قالب خود تبدیلات مقدار – نمایش را اعلان کنید. یک کلاس با دکوراتور @Pipe تابعی را تعریف میکند که مقادیر ورودی را به مقادیر خروجی تبدیل میکند تا در یک view نمایش داده شود.
Angular پایپهای متعددی را تعریف میکند که از جملهی اینها میتوان به پایپ ارز و تاریخ اشاره کرد. برای مشاهدهی لیست کامل API های پایپها به اینجا مراجعه کنید. همچنین میتوانید پایپهای جدیدی را تعریف کنید.
برای آن که داخل قالب HTML یک مقدار تبدیلی را مشخص کنید از عملگر پایپ (|) استفاده کنید.
{ {interpolated_value | pipe_name}}
میتوانید پایپها را به صورت زنجیرهای در آورید به این صورت که خروجی یک تابع پایپ را به تابع پایپ دیگر ارسال کنید تا این خروجی را تبدیل کند. پایپها میتوانند آرگومانهایی را بپذیرند که این آرگومانها نحوهی انجام این تبدیلات را توسط این پایپها کنترل میکنند. برای مثال میتوانید فرمت مورد نظر خود را به پایپ date بدهید.
< !-- Default format: output 'Jun 15, 2015'-- >
< p >Today is { {today | date}}< /p >
< !-- fullDate format: output 'Monday, June 15, 2015'-- >
< p >The date is { {today | date:'fullDate'}}< /p >
< !-- shortTime format: output '9:43 AM'-- >
< p >The time is { {today | date:'shortTime'}}< /p >
دستورالعملها
قالبهای Angular پویا هستند. وقتی که Angular آنها را رندر میکند، Angular بر اساس دستورالعملهای ارائه شده توسط directive ها DOM را تبدیل میکند. یک دستورالعمل به کلاسی با دکوراتور @Directive() گفته میشود.
کامپوننت ها از نظر فنی یک دستورالعمل محسوب میشوند؛ هرچند با توجه به این که کامپوننت ها تا حد زیادی متمایز هستند و در مرکز برنامههای Angular قرار دارند، Angular دکوراتور @Component() را تعریف میکند که این دکوراتور به همراه ویژگیهای قالب محور، دکوراتور @Directive() را توسعه میدهد.
علاوه بر کامپوننت ها دو نوع دیگر از دستورالعملها نیز وجود دارند: ساختاری (structural ) و صفت (attribute). Angular از هر دو نوع تعدادی از دستورالعملها را تعریف میکند و شما میتوانید با استفاده از دکوراتور @Directive() دستورالعمل خود را تعریف کنید.
متادیتاهای یک دستورالعمل درست مانند کامپوننت ها، کلاس آذین شده را به عنصر selector مرتبط میکند که شما میتوانید از این عنصر جهت درج این کلاس در HTML استفاده کنید. معمولاً دستورالعملهای موجود در قالبها به صورت صفتهایی با اسم و یا به صورت هدف یک تخصیص و یا binding داخل تگ یک عنصر ظاهر میشوند.
دستورالعملهای ساختاری
این دستورالعملها با اضافه، حذف و جابه جا کردن عناصر موجود در DOM، صفحه آرایی را تغییر میدهد. نمونه قالب زیر برای اضافه کردن منطق برنامه جهت مشخص کردن چگونگی رندر شدن view از دو دستورالعمل ساختاری توکار استفاده میکند.
src/app/hero-list.component.html (structural) < li *ngFor="let hero of heroes" >< /li > < app-hero-detail *ngIf="selectedHero" >< /app-hero-detail >
- *ngFor یک حلقهی تکرار است. این حلقه به Angular میگوید به ازای هر هیروی موجود در لیست heroes یکی از < li > ها را حذف کند.
- *ngIf یک دستور شرطی است که تنها در صورتی که هیروی انتخاب شده وجود داشته باشد، کامپوننت HeroDetail را شامل میشود.
دستورالعملهای صفت
این دستورالعملها ظاهر یا رفتار یک عنصر موجود را تغییر میدهند. این دستورالعملها در قالبها شبیه به صفتها و به دنبال آن اسامی HTML معمولی هستند.
دستورالعمل ngModel که از مقیدسازی دو طرفهی داده استفاده میکند، نمونهای از یک دستورالعمل صفت است. ngModel با تنظیم مقدار نمایش یک عنصر موجود (معمولاً < input >) و پاسخ دادن به تغییرات رویدادها، رفتار این عنصر را تغییر میدهد.
src/app/hero-detail.component.html (ngModel) < input [ (ngModel)]="hero.name" >
Angular دستورالعملهای از پیش تعریف شدهی بیشتری دارد که یا ساختار صفحه آرایی را تغییر میدهند (برای مثال ngSwitch) و یا جنبههای عناصر و کامپوننت های DOM را اصلاح میکنند (مانند ngStyle و ngClass).
در آموزش «دستورالعملهای ساختاری» و «دستورالعملهای صفتی» اطلاعات بیشتری در این باره کسب کنید.