با مطالعهی فصل ۹-۱ به اهمیت و ویژگی فرمها پی بردید و سپس با ارائهی یک مثال کاربردی نحوه استفاده از برخی امکانات موجود در ماژول NgForm را فرا گرفتید. در فصل گذشته رویکرد Template-Driven (کار کردن با قالب HTML برای ایجاد فرمها) را فرا گرفتید. اما فراموش نکردهاید که برای کار با فرمها در انگولار ۴ دو رویکرد وجود دارد. در این بخش قصد داریم به رویکرد دوم (Reactive Forms) پرداخته و فصل ۹ را به اتمام برسانیم. با ما همراه باشید.
شروع با یک مثال
مطابق فصل گذشته این مبحث را نیز با یک مثال ساده آغاز کرده و سپس امکانات مورد نیاز را به آن اضافه خواهیم کرد. بنابراین برای همراه بودن با مسیر آموزشی ما ابتدا مثال را از لینک پیوست شده در انتهای همین صفحه دریافت کنید و سپس سایر مراحل ارائه شده را مطالعه بفرمایید. پس از اجرای این فایل صفحهای مشابه زیر در اختیار شما قرار میگیرد که شامل یک فرم نام کاربری، ایمیل و جنسیت است.
بسیار عالی همانطور که ملاحظه میکنید این فرم شامل یک فیلد برای نام کاربری، یک فیلد برای ایمیل و فیلد دیگری برای تعیین جنسیت است. همچنین یک دکمه «ثبت» برای ارسال اطلاعات در انتهای فرم تعبیه کردهایم.
رویکرد Reactive
در کدنویسی فرمها با رویکرد Reactive، اکثر دستورها سمت کامپوننت نوشته خواهد شد. این رویکرد به شما کمک میکند تا فرمهایی با پیچیدگیهای خاص را به سادگی تولید کنید. برای درک بهتر مثال فوق را در اختیار داشته و سپس آن را ارتقاء میدهیم. بنابراین فایل app.component.ts را باز کرده و در ابتدا یک ویژگی از نوع FormGroup تعریف میکنیم. کلاس FormGroup مشخص میکند که کدام اطلاعات از کنترلر فرمها مدنظر ماست. در حالت کلیتر FormGroup به ویژگیای نسبت داده میشود که شامل تمام فرم است. بنابراین در اینجا نام این ویژگی را signupForm قرار میدهیم:
همچنین توجه داشته باشید که برای تولید فرمها با رویکرد Reactive همواره باید فایل app.module.ts را ویرایش کنیم زیرا ماژول FormsModule دیگر برای ما کاربردی ندارد (چون برای کار با قالب و رویکرد Template-Driven است). بنابراین در این فایل داریم:
همانطور که ملاحظه کردید ماژول ReactiveFormsModule را به فایل ماژولها اضافه کردیم. این ماژول شامل تمام ابزارهایی است که برای ساخت فرم بر پایه رویکرد Reactive نیاز داریم.
حال برای فعالکردن فرم در صفحه موردنظر باید ابتدا هوک ngOnInit را فعال کرده تا به هنگام فعال شدن کامپوننت فرم موردنظر ما نیز فعال شود. بنابراین در فایل app.component.ts داریم:
همانطور که ملاحظه میکنید ابتدا یک شیء جدید از کلاس FormGroup ایجاد کردیم که شامل تمام فرم است سپس از روی کلاس FormControl برای هر ورودی یا فیلد یک شیء جدید تولید و درون آرگومان آن مقدار Null (خالی) را ارسال کردهایم. تا مقدار پیشفرض هر فیلد ورودی خالی باشد. البته در نظر داشته باشید میتوانید با نوشتن هر عبارت دلخواه به صورت string درون علامت ” “، مقدار پیشفرض را برای ورودی خود در نظر بگیرید. اکنون در فیلد جنسیت مقدار پیشفرض «مرد» میباشد.
حال باید ارتباط بین قالب HTML و کلاس کامپوننت را برقرار کنیم. بنابراین فایل app.component.html را باز میکنیم و داخل تگ <form> دستور [FormGroup] را قرار داده تا به انگولار اطلاع دهیم که این گروه فرم ماست و مقدار آن را باید برابر با مقدار ویژگی FormGroup در کنترلر کامپوننت یعنی signupForm قرار دهید. همچنین باید برای انگولار هر فیلد ورودی را معرفی کنید و بگویید که به کدام FormControl در کلاس کامپوننت مربوط میشود. پس در این فایل باید تغییرات زیر را اعمال کنیم:
بسیار عالی در این حالت فرم HTML شما به انگولار آغشته شده است. حال میخواهیم هنگامیکه روی دکمهی «ثبت» کلیک شد. اطلاعاتی در اختیار ما قرار بگیرد. برای انجام این کار همانند رویکرد Template-Driven باید از دستور ویژگی ngSubmit استفاده کرده و سپس آن را به یک متد onSubmit واگذار کنیم. تا به اینجای کار همه چیز دقیقا مشابه رویکرد Template-Driven است ولی در رویکرد Reactive نیازی به تعریف یک قالب لوکال نیست. زیرا فرم ما هم اکنون توسط انگولار شناخته شده است. بنابراین ابتدا در فایل app.component.html به تگ <form> تغییرات زیر را اضافه خواهیم کرد:
سپس درون فایل app.component.ts متد onSubmit را تعریف میکنیم:
پس از وارد کردن آدرس http://localhost:4200 در صفحه کنسول شما اطلاعات جامعی درباره این فرم در قالب FormGroup در اختیارتان قرار میگیرد.
اعتبارسنجی در رویکرد Reactive
برای اعتبارسنجی در این رویکرد باید به آرگومانهای سازنده پیشفرض کلاس FormControl در کلاس کامپوننت اشاره کنیم. آرگومان دوم این سازنده برای اعتبارسنجی فرمها مورد استفاده قرار میگیرد. برای درک بهتر از این موضوع دستورهای زیر را درون فایل app.component.ts اجرا میکنیم:
خب تا اینجای کار همه چیز به درستی اعمال شده است. حالا ما میخواهیم هنگامیکه اعتبارسنجی با خطا روبهرو شد متن پیام خطا نمایش داده شود. برای انجام اینکار از یک دستور شرطی if استفاده کرده و مقدار عبارت شرطی را برابر با اطلاعاتی که از formControlها بدست میاوریم قرار میدهیم. متد get اطلاعات موجود در یک FormControl را در اختیار میگذارد. بنابراین در فایل app.component.html خواهیم داشت:
همچنین برای زیباتر شدن فایل app.component.css را به صورت زیر تنظیم کنید:
در صورتیکه تمام مراحل فوق را به درستی انجام داده باشید خروجی شما به صورت زیر خواهد بود:
حال فرض کنید میخواهیم یک فرم تو در تو درست کنیم. یعنی چی؟ یعنی میخواهیم همانند رویکرد اول مثلا دادههای مربوط به نام کاربری و ایمیل را درون یک متغییر به نام userData در اختیار داشته باشیم در این حالت باید ابتدا در فایل app.component.ts یک FormGroup ایجاد کنیم و سپس دادهها را به آن منتقل نماییم:
سپس فایل app.component.html را به صورت زیر ویرایش کنیم. توجه داشته باشید که از یک تگ <div> جدید استفاده کردهایم و ویژگی formGroupName را برای آن فعال کرده تا نام این گروه فرم جدید را به آن معرفی کنیم:
حال اگر این مثال را در آدرس http://localhost:4200 اجرا کنیم مجددا با خروجی قبلی روبهرو خواهیم شد چون فقط یک کلاس فرم جدید به این مجموعه اضافه کردهایم.
آرایههای Reactive فرم کنترلها (Form Controls)
گاهی نیاز داریم که یک یا ده یا صد عدد از فرمکنترل ها را درون یک آرایه در اختیار داشته باشیم. مثلا فرض کنید میخواهیم یک دکمه به نام «افزودن تگ» در صفحه قرار دهیم تا با هر بار کلیک کردن روی آن یک فرم کنترل یا ورودی Input ارسال و ذخیره گردد. در این حالت باید از FormArrayها استفاده کنیم. بنابراین در فایل app.component.html داریم:
حال باید این آرایهی فرم کنترلر را داخل فایل app.component.ts تعریف کنیم. برای انجام اینکار داریم:
چگونه اعتبارسنجی دلخواه در رویکرد Reactive تولید کنیم؟
برای تفهیم این موضوع فرض کنید میخواهیم یک محدودیت برای انتخاب نام کاربری درنظر بگیریم. یعنی کاربر به هنگام انتخاب نام کاربری نمیتواند این نام را انتخاب کند. بنابراین فایل app.component.ts را باز کرده و در نهایت یک ویژگی به نام forbiddenUsername تعریف میکنیم که مقادیری را به عنوان نام کاربری ممنوعه یا غیرمجاز دریافت میکند:
سپس باید یک متد برای ارائهی فرمانهای کنترلی و محدودکننده ایجاد کنیم. بنابراین در ادامه همین فایل خواهیم داشت:
همانطور که ملاحظه میکنید یک متد به نام forbiddenName با ورودی control ایجاد کردیم که پس از پردازش نام کاربری و مقایسه آن با اسامیای که درون ویژگی forbiddenUsername قرار دارند، خروجیای به صورت باینری یا بولین نمایش میدهد حال این اعتبار سنجی را در قسمت مربوط به username و درون یک آرایه اعمال کردیم.
اگر آدرس http://localhost:4200 را باز کنید متوجه خواهید شد که خطایی در صفحه کنسول بوجود آمده است. این خطا برای این است که کلمه کلیدی this درون اعتبارسنجی this.forbiddenName به این کلاس اشاره نمیکند بلکه به کلاس Validators اشاره خواهد کرد و این اشتباه است چون متد forbiddenName درون این کلاس قرار دارد. بنابراین برای حل این مشکل از متد bind استفاده کرده و this را در این کلاس مورد استفاده قرار میدهیم:
بسیار عالی حال اگر نام کاربری را درون فرم برابر roxo یا admin قرار دهید در المان div مربوط به ورودی username کلاس ng-invalid نمایش داده میشود.
یکی از ابزارهای جالبی که در کار کردن با فرمها در حالت Reactive مورد توجه است استفاده از ویژگی error در هر فرم کنترلر میباشد که در ادامه به توضیح آن میپردازیم.
بکارگیری ویژگی error در رویکرد Reactive
اگر فرم مثال قبلی را در آدرس http://localhost:4200 پر کنید و سپس روی دکمهی ثبت کلیک نمایید. در صفحه کنسول یک شیء FormGroup برای شما ایجاد میشود که با کلیک کردن روی آن یک ویژگی به نام errors در اختیار شما قرار میگیرد. با استفاده از این ویژگی میتوان مشخص کرد که کدام متن خطا برای کاربر به نمایش گذاشته شود. به عنوان مثال برای فیلد نام کاربری در فایل app.component.html خواهیم داشت:
در واقع با استفاده از ویژگی errors به هر خطایی که مدنظرمان است دست پیدا کرده و متناسب با آن پیامی را برای مخاطب ارسال میکنیم.
بروزرسانی یک فیلد دلخواه patchValue
همانطور که در رویکرد Template-Driven مشاهده کردید میتوان تنها یک فیلد از فرم را برای پیشنهاد نام کاربری تغییر داد و نیازی به ایجاد شیء از تمام فیلدها نیست. در رویکرد Reactive نیز این متد برقرار است و شما میتوانید با استفاده از آن تنها یک فیلد را بروزرسانی کنید.
بسیار عالی به شما عزیزان تبریک میگوییم. با مطالعهی فصل ۹ توانایی ساخت انواع فرمهای پیشرفته را کسب کردید. در ادامهی این سری از دورههای مجموعه آموزشی انگولار ۴ به آموزش مباحثی چون pipe، درخواستهای Http در فصول آینده میپردازیم. با ما همراه باشید.
توجه: دوستان عزیز آموزش ویدیویی انگولار ۵ از مقدماتی تا پیشرفته به زبان فارسی را میتوانید با کلیک روی اینجا یاد بگیرید. (این دوره در حال برگزاری است)
فصل ۱
فصل ۲
- بخش ۱: معرفی چرخه حیات Life Cycle انگولار ۴
- بخش ۲: معرفی کامپوننتها (Components) در انگولار ۴
- بخش ۳: کامپوننتها و ایجاد خودکار آنها در انگولار ۴
- بخش ۴: معرفی Databinding (ارتباطات دادهای) در انگولار ۴
- بخش ۵: معرفی رویدادها (Event) و ارتباط آن با Databinding در انگولار ۴
- بخش ۶: مقدمهای بر دستورها (Directives) در انگولار ۴
فصل ۳: خطایابی (Debugging) در انگولار ۴
فصل ۴
- بخش ۱: ارسال داده بین کامپوننتها (والد به فرزند و فرزند به والد) در انگولار ۴
- بخش ۲: معرفی مبحث Encapsulation (کپسولهسازی) در انگولار ۴
- بخش ۳: معرفی Local Reference ها در قالبهای HTML در انگولار ۴
- بخش ۴: معرفی چرخه حیات (lifecycle) و هوک (hook) در انگولار ۴
فصل ۵
- بخش ۱: ساخت دستورهای صفتی (Attribute Directive) دلخواه در انگولار ۴
- بخش ۲: ارسال اطلاعات به ویژگیها (Property) و پاسخ به رویدادها (Event) در دستورهای صفتی
- بخش ۳: ایجاد دستورهای ساختاری (Structural Directive) در انگولار ۴
فصل ۶
- بخش ۱: معرفی سرویسها (Service) و تزریق وابستگی (Dependency Injection) در انگولار ۴
- بخش ۲: معرفی تزریق سرویسها (Service) درون یکدیگر در انگولار ۴
فصل ۷
- بخش ۱: معرفی مسیریابی (Routing) در انگولار ۴
- بخش ۲: معرفی پارامترهای موجود در آدرسها (Url) در انگولار ۴
- بخش ۳: تعیین سطح دسترسی برای مسیرها در انگولار ۴
- بخش ۴: امنیت در مسیردهی (Routing Guard) در انگولار ۴
فصل ۸: معرفی Observable یا مشاهده کنندهها در انگولار ۴
فصل ۹
- بخش ۱: معرفی فرمها و رویکرد Template-Driven در انگولار ۴
- بخش ۲: معرفی فرمها و رویکرد Reactive در انگولار ۴
فصل ۱۰: معرفی فیلترها یا Pipes در انگولار ۴
فصل ۱۱: معرفی درخواستهای Http در انگولار ۴
منبع: روکسو