در بخش ۱-۳ شما موفق به تولید یک نرمافزار بسیار ساده شدید. همچنین با مفاهیمی چون ngFor و Input جهت تکرار و ارسال داده از کامپوننت والد به فرزند آشنا شدید. در این جلسه قصد دارم کمی دقیقتر و ریزتر مفاهیم خودراهاندازی را در انگولار ۲ مورد بررسی قرار دهیم. با ما همراه باشید.
هر اپلیکیشنی یک نقطهی شروع دارد و آن استفاده از angular-cli میباشد که به عنوان ابزار webpack شناخته میشود. نیازی به یادگیری webpack برای استفاده از انگولار نیست. اما یادگیری چگونگی راهاندازی و اجرای اپلیکیشن شما، میتواند برایتان مفید باشد.
ما هر اپلیکیشن را با اجرای دستور زیر راهاندازی میکنیم:
ng serve
ng درون فایل angular-cli.json به جستجو میپردازد تا نقطهی شروع یک اپلیکیشن را پیدا کند. حال نشان میدهیم که چگونه ng کامپوننتی را برای اجرا پیدا میکند. در سطوح بالاتر اینطوری به نظر میرسد:
درباره این فرایند به تفصیل صحبت خواهیم کرد. اما در این مرحله روی سیستم Angular Module یا NgModules تمرکز میکنیم.
انگولار به معنای دقیق کلمه یک سیستم module قدرتمند دارد. هنگامی که شما نرم افزار انگولاری خود را اجرا میکنید، یک کامپوننت را به صورت مستقیم راهاندازی نمیکنید بلکه یک NgModule به عنوان نقطه شروع برنامهی خود تولید میکنید. نگاهی به کدهای زیر بیاندازید:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; import { HelloWorldComponent } from './hello-world/hello-world.component'; import { UserItemComponent } from './user-item/user-item.component'; import { UserListComponent } from './user-list/user-list.component'; @NgModule({ declarations: [ AppComponent, HelloWorldComponent, UserItemComponent, UserListComponent ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
در ابتدای کار شما یک مفسر @NgModule را مشاهده میکنید. مشابه تمام مفسرها، کد @NgModule() یک سری اطلاعات و دادهها را برای کلاس AppModule فراهم میکند.
مفسر @NgModule سه کلید اصلی دارد: declarations, imports و bootstrap
declarations کامپوننتهایی که در این ماژول تعریف شدهاند را مشخص میکند. شاید برای شما این سوال پیش بیاید چگونه وقتی دستور ng generate را وارد میکنید، یک کامپوننت با تمام الحاقات آن ساخته میشود! یک اصل و ایدهی اساسی در انگولار هست که میگوید:
شما باید هر کامپوننتی را قبل از استفادهی آن در قالب خود، در NgModule تعریف کنید.
imports تمام وابستگیهای این ماژول را تعریف میکند. در واقع ما یک اپلیکیشن مرورگر ساختهایم بنابراین باید ماژول BroserModule را import کنیم.
bootstrap به انگولار اطلاع میدهد که هر وقت این ماژول برای اجرای یک اپلیکیشن راهاندازی شد، حتما AppComponent را به عنوان بالاترین کامپوننت به کار بگیرد.
تا به اینجای کا ما یاد گرفتیم که چگونه یک اپلیکیشن پایه را راهاندازی کنیم. شروع به ساخت Reddit میکنیم. قبل از شروع به برنامهنویسی، بهتره یک دید کلی از نرمافزار خود داشته باشیم و آن را به تکههای کوچکتر در کامپوننتهای منطقی تبدیل کنیم. به تصویر زیر دقت کنید:
برای ساخت این اپلیکیشن نیاز به دو کامپوننت اصلی داریم:
توجه: در نرمافزارها و اپلیکیشنهای بزرگ، ممکن است فرمهای ثبت مطالب داخل کامپوننت اصلی تعریف شوند. هرچند نوشتن فرمها در کامپوننتهای اصلی روش ارسال داده را بسیار پیچیده میکند..
در ابتدای کار بهتر است از نرمافزار قبلی که تحت عنوان angular2_hello_world ایجاد کردیم، چشمپوشی کرده و نرمافزاری جدید را با دستور new تولید کنید. بنابراین داریم:
ng new angular2_reddit
هماکنون باید یک کامپوننت جدید را که دارای ویژگیهای زیر است، بسازید:
میتوان اصلیترین کامپوننت اپلیکیشن را در مسیر src/app/app.component.ts پیدا کرد تا اطلاعات اولیهای را درون آن مشابه قبل قرار داد:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app works!'; }
باید قالب این کامپوننت را که یک قالب پیشفرض است تغییر داده تا پیکرهی نرمافزار اصلی ما ظاهری مناسبتر داشته باشد، در نتیجه app.component.html را بنا به سلیقه خود طراحی کنید. برای طراحی حرفهای میتوانید از فریمورکهای CSS و HTML استفاده کرد که معروفترین آنها فریمورکهای getbootstrap, getUikit, Foundation, Semantic میباشد. در اینجا ما از فریم ورک bootstrap استفاده میکنیم:
<div class="row"> <!-- Horizontal Form --> <div class="col-md-8 col-center-block"> <div class="box box-info"> <div class="box-header with-border"> <h3 class="box-title">ثبت لینک</h3> </div> <!-- /.box-header --> <!-- form start --> <form class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label for="title" class="col-sm-2 control-label">عنوان مطلب</label> <div class="col-sm-10"> <input type="text" class="form-control" name="title" placeholder="عنوان مطلب خود را وارد کنید"> </div> </div> <div class="form-group"> <label for="link" class="col-sm-2 control-label">لینک</label> <div class="col-sm-10"> <input type="text" class="form-control" name="link" placeholder="لینک مطلب را وارد کنید"> </div> </div> </div> <!-- /.box-body --> <div class="box-footer"> <button type="submit" class="btn btn-info pull-right">ثبت</button> </div> <!-- /.box-footer --> </form> </div> </div> </div> <!-- /.box -->
همانگونه که مشاهده میکنید در template موردنظر به استثنای تگهای تزئینی HTML دو تگ اصلی input به فرم اضافه کردهایم. یکی تگ title و دیگری link. در صورتیکه مرورگر خود را بروزرسانی کنید با تصویری مشابه، تصویر ذیل روبهرو خواهید شد:
هماکنون یک فرم با تگهای ورودی input داریم اما هیچ اطلاعاتی از طریق فرم ما ثبت نمیشود. چون در تگ دکمه <button> هیچگونه رویدادی تعریف نشده است که اگر کاربر این دکمه را فشرد عکسالعملی نشان دهد. درواقع ما میخواهیم وقتی یک فرم ثبت شد تابعی فراخوانی شود. برای اینکار یک رویداد تعاملی به دکمهی button خود اضافه میکنیم.
در عمل از انگولار درخواست میکنیم که نسبت به رویداد تعریف شده پاسخی ارسال کند. هر رویداد دارای یک عنوان است که در انگولار ۲ این عنوان داخل یک جفت پرانتز () تعریف میشود. برای مثال جهت اضافه کردن یک رویداد به هنگام کلیک کردن روی یک دکمه یا همان رویداد onClick میتوان تابع addArticle() را فراخوانی کرد. به مثال زیر توجه کنید:
<div class="box-footer"> <button type="submit" (click)="addArticle()" class="btn btn-info pull-right">ثبت</button> </div>
با اجرای دستور بالا، هر وقت روی دکمهی «ثبت» کلیک شود، تابع addArticle() فراخوانی میشود. حال باید تابع addArticle() را داخل کلاس AppCompnent تعریف کنیم. بنابراین داریم:
export class AppComponent { addArticle(title: HTMLInputElement, link: HTMLInputElement): boolean { console.log('Adding article title: ${title.value} and link: ${link.value}'); return false; } }
همانگونه که ملاحظه میکنید تابع addArticle دارای دو آرگومان به نامهای title و link است. حال نیاز به تغییرات دکمهی «ثبت» داریم. زیرا باید آرگومان تابع addArticle() در دکمه تغییر کند و دو ورودی بگیرد. همچنین باید متغییرهای ارسالی به این تابع نیز در فرم template برای المانهای input اعمال شود. بنابراین:
<div class="row"> <!-- Horizontal Form --> <div class="col-md-8 col-center-block"> <div class="box box-info"> <div class="box-header with-border"> <h3 class="box-title">ثبت لینک</h3> </div> <!-- /.box-header --> <!-- form start --> <form class="form-horizontal"> <div class="box-body"> <div class="form-group"> <label for="title" class="col-sm-2 control-label">عنوان مطلب</label> <div class="col-sm-10"> <input type="text" class="form-control" name="title" placeholder="عنوان مطلب خود را وارد کنید" #newtitle> </div> </div> <div class="form-group"> <label for="link" class="col-sm-2 control-label">لینک</label> <div class="col-sm-10"> <input type="text" class="form-control" name="link" placeholder="لینک مطلب را وارد کنید" #newlink> </div> </div> </div> <!-- /.box-body --> <div class="box-footer"> <button type="submit" (click)="addArticle(newtitle, newlink)" class="btn btn-info pull-right">ثبت</button> </div> <!-- /.box-footer --> </form> </div> </div> </div> <!-- /.box -->
مطابق با تغییرات بالا در المانهای input متغییرهایی را جهت ذخیرهسازی اطلاعاتی که توسط کاربر نوشته میشوند، تعریف کردیم. این متغییرها با علامت # مشخص و به عنوان متغییرهای محلی شناخته میشوند. با اضافه کردن متغییرهای #title و #link به المانهای input میتوان اطلاعات را به تابع addArticle() ارسال کرد.
برای یادآوری تغییرات انجام شده را لیست میکنیم:
این مسیر رو به جلوی ما بود، حال برای اینکه این مباحث به صورت کامل برای شما جا بیافتد یکبار دیگر از آخر به اول تمام این مراحل را ریز به ریز بررسی کرده و توضیح میدهیم:
اتصال مقادیر وارد شده در input به متغییرهای حامل
در تگهای input متغییرهای محلی جهت حمل اطلاعات و ارسال آنها به تابع addArticle() ایجاد شد. این صفات به انگولار میگویند که اطلاعات وارد شده توسط کاربر در input را به متغیرهای #newtitle و #newlink وصل کن! سینکتس #newtitle یک تصمیم (resolve) نامیده میشود. با این شرایط newtitle یک شیء میباشد که المان input DOM را نمایش میدهد (به طور مشخص، نوع این متغییرها HTMLInputElement میباشد). زیرا newtitle یک شیء است و در نتیجه مقدار ورودی متصل شده به آن با استفاده از newtitle.value قابل دسترس است.
اتصال actionها به رویدادها
در تگ button صفت (click) برای زمانیکه کاربر روی دکمه کلیک کرده بود، تعریف شده است. هنگامیکه رویداد (click) رخ دهد، تابع addArticle فراخوانی میشود که دارای دو ورودی newtitle و newlink است. این تابع و دو آرگومان از کجا آمدهاند؟
مجموع این تفاسیر به شکل زیر خواهد بود:
<button type="submit" (click)="addArticle(newtitle, newlink)" class="btn btn-info pull-right">ثبت</bu
تعریف Actionهای منطقی
در کلاس AppComponent تابعی تحت عنوان addArticle تعریف شده است. این تابع دو آرگومان دارد: ۱) title و ۲) link. مجددا اشاره میکنیم که title و link هر دو شیءهایی (Object) از نوع HTMLInputElement هستند و توجه کنید که به عنوان مقادیر مستقیم inputها شناخته نمیشوند. برای دستیابی به مقادیر input از دستور title.value استفاده میکنیم. همچنین خروجی را در کنسول با دستور console.log و آرگومانهایش به نمایش میگذاریم.
export class AppComponent { addArticle(title: HTMLInputElement, link: HTMLInputElement): boolean { console.log(`Adding article title: ${title.value} and link: ${link.value}`); return false; } }
توجه: اگر به مجموعهی کد موجود در شیء console دقت کنید، متوجه خواهید شد که از علامت ` یا به اصطلاح backtick استفاده شده است. این ویژگی در ES6 مطرح شده است که منجر به توسعه متغییرهای قالب میشود. در تابع addArticle() از عبارت ${title.value} استفاده شده است که با مقدار title.value جایگزین میشود.
برای نهایی کردن این قسمت روی دکمهی «ثبت» کلیک کنید و درصورتیکه تمام کدها را به درستی وارد کرده باشید با تصویر زیر روبهرو خواهید شد.
با بررسی و پیش بردن مراحل بالا شما توانایی ایجاد یک کامپوننت با قابلیت نمایش دادههای ثبت شده را دارید. مرحله نخست طراحی سایت نظرسنجی با انگولار 2 که مشابه سایت reddit است، به اتمام رسید. حال شما باید قسمت دوم که با رنگ سبز مشخص شده بود را تکمیل کنید. این قسمت نیاز به توضیحات بیشتری دارد که در بخش ۱-۵ به تفصیل مورد بررسی قرار میگیرد.
برای افزایش تمرکز کاربران عزیز و جلوگیری از طولانی شدن مطالب، هر بخش را به قسمتهای کوچکتری تبدیل کردهایم. در لیست زیر تمام بخشها و زیربخشهای آموزشی مجموعهی انگولار ۲ در اختیار شما قرار گرفته است.
توجه: دوستان عزیز آموزش ویدیویی انگولار ۵ از مقدماتی تا پیشرفته به زبان فارسی را میتوانید با کلیک روی اینجا یاد بگیرید. (این دوره در حال برگزاری است)
فصل ۱
فصل ۲
فصل ۳
فصل ۴
فصل ۵
فصل ۶
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.