اینک وارد بحث جدیدی از سری دورههای آموزش فارسی انگولار ۲ میشویم. از عنوان این فصل مشخص است که با چه مقولهی مهمی برخورد کردیم. کاملا درست فکر میکنید! فرمها به عنوان مهمترین و پیچیدهترین بخشهای هر وبسایت و یا نرمافزار تحت وب را تشکیل میدهند. اهمیت این فرمها زمانی مشخص میشود که بخواهید اطلاعاتی را از طریق یک دکمه و Event به مکان دیگری (که میتواند دیتابیس و یا هر چیز دیگهای باشد) انتقال دهید. در ابتدا شاید به این فکر کنید که فرمها را میتوان با یک تگ input ساخت و به راحتی از کاربر تقاضا کرد که اطلاعات خود را وارد باکس موردنظر کند. اما آیا واقعا کار به همین سادگی است؟ مسلما جواب منفی است. برای روشن تر شدن این موضوع چند چالش عمده فرمها را ارائه خواهیم داد:
حال انگولار ۲ به عنوان یک راهنمای بلامنازع به شما کمک میکند تا این مسائل و چالشها را برطرف کنید.
حال در ادامهی توضیحات این بخش به صورت مرحله به مرحله نحوه ساخت یک فرم را آموزش میدهیم. مثالها از سادهترین سطح ممکن شروع و به پیچیدهترین حالت ختم میشوند.
دو شیء اساسی و بنیادی در فرمهای انگولار ۲ FormControl و FormGroup هستند.
FormControl
یک FormControl برای نمایش یک فیلد ورودی بکار گرفته میشود که کوچکترین عضو یک فرم انگولار بحساب میآید. به بیان دیگر FormControlها به عنوان یک فیلد ورودی با تگ input در فرمهای انگولار شناخته شده که کوچکترین المان یک فرم محسوب میشود. FormControlها مقادیر فیلدها را کپسوله میکنند و شرایط مختلف آنها اعم از اعتبارسنجی، تغییر متن یا خطا را مورد ارزیابی قرار میدهند. برای نمونه در مثال زیر نحوه استفاده از FormControlها را مورد بررسی قرار میدهیم:
// ساخت یک فرم کنترلر جدید به همراه مقدار nate let nameControl = new FormControl("Nate"); let name = nameControl.value; // -> Nate // هم اکنون میتوان برای این مقدار مشخص دستورهای ارزیابی اعتبار سنجی و خطا را مورد بررسی قرار داد nameControl.errors // -> StringMap<string, any> of errors nameControl.dirty // -> false nameControl.valid // -> true // etc.
همانگونه که در مثال فوق ملاحظه کردید ابتدا یک فیلد ورودی به نام nameControl تعریف کرده و مقدار پیشفرض آن را nate قرار دادیم. حال برای دسترسی به این مقدار از دستور nameControl.value استفاده خواهیم کرد. علاوه بر متد value سایر متدها مانند errors, dirty و valid وجود دارند که به شرح زیر عمل میکنند:
تمام ویژگیهای فوق زمانی که درست یا غلط باشند مقادیر True و False را باز میگردانند.
همانند سایر مباحث، در انگولار ۲ یک کلاس تحت عنوان FormControl داریم که به DOM به همراه یک صفت formControl متصل میشود. در مثال زیر نحوه استفاده کردن از این فرم کنترلر را در کد HTML یا DOM مورد بررسی قرار میدهیم:
<input type="text" [formControl]="name" />
این خط یک شیء FormControl جدید درون فرم ما ایجاد کرد. در ادامه به نحوه کارکرد آن اشاره خواهیم کرد.
FormGroup
بسیاری از فرمها، بیش از یک فیلد دارند. بنابراین ما به تعداد بیشتری FormControls نیاز داریم و اگر بخواهیم اعتبارسنجی فرم خود را بررسی کنیم، باید آرایهای از FormControlها را ایجاد کرده و هر یک را ارزیابی کنیم. این کار بسیار زمان بر و از نظر مهندسی طراحی نرمافزار اشتباه میباشد لذا برای حل این مسئله از FormGroupها استفاده میشود که در واقع مجموعهای از FormControlها را در بر میگیرند.
یک نمونه جهت ایجاد FormGroupها:
let personInfo = new FormGroup({ firstName: new FormControl("Nate"), lastName: new FormControl("Murray"), zip: new FormControl("90210") })
بنابراین میتوانیم status یا value را برای personInfo بررسی کنیم:
personInfo.value; // -> { // firstName: "Nate", // lastName: "Murray", // zip: "90210" // } personInfo.errors // -> StringMap<string, any> of errors personInfo.dirty // -> false personInfo.valid // -> true // etc.
همانطور که در جریان هستید فرمها نکات بسیار ریزی دارند که با ارائهی یک مثال کامل بروز پیدا میکنند. در این بخش یک مثال جامع در ارتباط با ساخت فرمها در اختیار شما قرار میدهیم:
تصویر زیر نمایانگر فرمی است که مدنظر ما میباشد:
تصور کنید که وب سایتی برای فروشگاه اینترنتی آنلاین طراحی کرده اید و قصد دارید لیست محصولات خود را متناسب با کد محصول وارد کنید بنابراین نیاز به یک فرم دارید که ورودی را دریافت کند و آن را تحت عنوان کد محصول ذخیره نماید. در نظر دارید که کد محصول به طور معمول با عبارت SKU مطرح میشود. این کلمه مخفف عبارت Stock Keeping Unit است. هر محصول یک کد یکتا دارد. این کد گاها برای ارسال و پست محصول مورد استفاده قرار میگیرد.
فرم ما بسیار ساده است: یک ورودی برای sku به همراه یک برچسب و یک دکمهی «ذخیره» برای ثبت اطلاعات در اختیار داریم. اجازه بدهید این فرم را تحت عنوان یک کامپوننت ایجاد کنیم. اگر به یاد داشته باشید، برای تعریف یک کامپوننت به ۳ قسمت نیاز داریم:
شروع میکنیم:
برای ایجاد کردن یک فرم جدید در انگولار ۲ باید مطمئن شویم که کتابخانههای موردنظر فرمها درون NgModule فراخوانی یا Import شده باشند. همواره دو راه برای استفاده از فرمها در انگولار ۲ وجود دارد که هر دو روش را به دقت بررسی خواهیم کرد. روش اول استفاده از FormsModule ها و روش دوم استفاده از ReactiveFormsModule میباشد. برای اینکه هر دو روش را توضیح دهیم، هر دو ماژول را در NgModule فراخوانی میکنیم. بنابراین فایل app.ts را به صورت زیر ویرایش می کنیم:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, FormsModule, ReactiveFormsModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
اضافه کردن این خطوط به کد برنامه تضمینی است جهت استفاده از دستورهای فرمها داخل view نرم افزار شما. در واقع FormsModule، مجموعهای از دستورهای موردنیاز برای طراحی قالب یک فرم (مثال: ngModel و NgForm) را در اختیار شما قرار میدهد. درحالیکه کتابخانه ReactiveFormsModule دستورهایی مشابه: formControl و ngFormGroup را در اختیار میگذارد.
هم اکنون شروع به بازنویسی کامپوننت میکنیم:
import { Component } from '@angular/core'; @Component({ selector: 'demo-form-sku',
در این بخش یک سلکتور (selector) به نام demo-form-sku تعریف کردیم. اگر به یاد داشته باشید، سلکتورها به انگولار میگویند که چه المانی از این کامپوننت برای نمایش در خروجی قالب مورد استفاده قرار میگیرد. در واقع تگ موردنظر را جهت استفاده در کد HTML تعیین میکند:
<demo-form-sku></demo-form-sku>
حال برای کدنویسی قالب فرم موردنظر، فایل app.component.html را باز کرده و کدهای زیر را جایگزین میکنیم:
<div class="row"> <div class="col-md-8 container-center"> <div class="box box-info"> <div class="box-header with-border"> <h3 class="box-title">ثبت کد محصول</h3> </div> <div class="box-body"> <form #skuForm="ngForm" (ngSubmit) = "onSubmit(skuForm.value)" class="form-horizontal"> <div class="form-group"> <label for="skuInput" class="col-sm-2 control-label">کد محصول</label> <div class="col-sm-10"> <input type="text" class="form-control" id="skuInput" name="sku" placeholder="کد محصول را وارد کنید..." ngModel> </div> </div> <div class="box-footer"> <button type="submit" class="btn btn-info pull-left">ذخیره</button> </div> </form> </div> </div> </div> </div>
شگفتزده شدهاید؟ کاملا حق با شماست! یک سری دستورها را فقط کپی پیست کردهاید! اما نگران نباشید. در این بخش به صورت کامل توضیحات مربوط به مثال فوق را ارائه خواهیم داد.
form و NgForm
در ابتدای کار FormsModule را import کردیم تا بتوانیم از امکانات NgForm در view بهرهمند باشیم. به یاد داشته باشید که هر گاه در انگولار ۲ از دستوری استفاده کردیم، در واقع آن را به تمام المانهایی که شامل آن سلکتور هستند اتصال دادهایم.
NgForm به صورت غیرآشکارا یک سری کلاسها را به فرم ما اضافه میکند: یعنی اگر FormsModule را فراخوانی یا import کنیم، NgForm به صورت خودکار به تمام تگهای <form> اضافه خواهد شد. حال دو تابع بسیار مهم وجود دارد که NgForm در اختیار ما قرار میدهد:
همانگونه که ملاحظه میکنید هر دو تابع فوق درون تگ <form> ما قرار گرفته است:
<form #skuForm="ngForm" (ngSubmit) = "onSubmit(skuForm.value)" class="form-horizontal">
در واقع، در ابتدای کار عبارتی معادل skuForm = "ngForm# را ایجاد کردیم. سینتکس variableName=directive به ما اطلاع میدهد که یک متغییر محلی برای این ویو ساخته شد. در اینجا ما یک نام مستعار یا متغییر تحت عنوان skuForm# برای ngForm قرار داده ایم. حال این سوال پیش میآید که نوع شیء ngForm چیست؟ جواب سوال: نوع آن FormGroup است. بدین معنی که ما از skuForm به عنوان یک FormGroup در ویو خود استفاده کردهایم.
در انتها اطلاعات را روی اکشن ngSubmit ارسال خواهیم کرد که با سینتکس زیر مشخص شده است:
(ngSubmit) = "onSubmit(skuForm.value)"
در یک خط میتوان تمام مراحل بالا را به زبان سادهتری بیان کرد:
هنگامیکه من فرم را ذخیره کردم تابع onSubmit در کامپوننت اجرا شده و مقادیر ورودیها را به عنوان یک آرگومان ارسال خواهد شد.
input و NgModel
تگ input دارای یک سری ویژگیها و صفات است که برای آشنایی با آنها باید HTML و مباحث Classهای هر المان را آموزش دیده باشید. طبیعتا از توضیح آنها صرف نظر میکنیم و به NgModel میپردازیم:
دستور NgModel یک سلکتور (selector) از ngModel را مشخص میکند. بدین معنی که میتوان آن را با استفاده از صفت ngModel="whatever" به تگ input متصل کرد. در این مثال، صفت ngModel بدون مقدار است. NgModel یک FormControl جدید را ایجاد کرده که به صورت خودکار به FormGroup والد خود اضافه میشود و سپس اطلاعات را به یک المان DOM بایند میکند. به بیان سادهتر، NgModel یک رابطه بین تگ input و FormControl توسط نام sku برقرار میکند.
بیشتر بخوانید: تفاوت بین NgModel و ngModel : در حالت کلی هنگامیکه از کلمهای با ساختار PascalCase استفاده کردیم (مانند NgModel) به یک کلاس مشخص اشاره میکنیم اما اگر از کلمهای با ساختار CamelCase (مانند: ngModel) بهرهبردیم، به یک سلکتور (selector) از دستورالعمل اشاره کردهایم که تنها در قالبهای HTML و DOM قابل استفاده هستند.
کار ما هنوز به اتمام نرسیده است چون با کلیک کردن روی دکمهی ذخیره هیچ اتفاقی نمیافتد. بنابراین به کلاس کامپوننت مراجعه کرده و کدهای زیر را به آن اضافه میکنیم:
export class AppComponent { onSubmit(form: any): void{ console.log('کد محصول ثبت شده برابر است با:', form); } }
با مطالعهی کد بالا متوجه خواهید شد که پیچیدگی خاصی وجود ندارد. تابع onSubmit یک آرگومان به نام form از نوع any دارد که به محض اجرای تابع به خروجی مرورگر و در کنسول آن نمایش داده خواهد شد.
تا به اینجای کار شما با نحوهی ساخت یک فرم ساده به همراه تمام امکانات اعم از ورودی، دکمهی ذخیرهسازی، ارسال اطلاعات و ... آشنا شدید. مباحث فرمها همانطور که در ابتدای این بخش مطرح شد بسیار مهم و ارزشمند میباشد. در ادامه به توضیح مفصل FormBuilder ها در انگولار ۲ میپردازیم. نفسی تازه کرده و به بخش ۴-۲ مراجعه کنید.
برای افزایش تمرکز کاربران عزیز و جلوگیری از طولانی شدن مطالب، هر بخش را به قسمتهای کوچکتری تبدیل کردهایم. در لیست زیر تمام بخشها و زیربخشهای آموزشی مجموعهی انگولار ۲ در اختیار شما قرار گرفته است.
توجه: دوستان عزیز آموزش ویدیویی انگولار ۵ از مقدماتی تا پیشرفته به زبان فارسی را میتوانید با کلیک روی اینجا یاد بگیرید. (این دوره در حال برگزاری است)
فصل ۱
فصل ۲
فصل ۳
فصل ۴
فصل ۵
فصل ۶
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.