ویرگول
ورودثبت نام
رهام رفیعی تهرانی
رهام رفیعی تهرانیبرنامه نویسی یک شغل نیست، یک هنره.
رهام رفیعی تهرانی
رهام رفیعی تهرانی
خواندن ۴ دقیقه·۳ سال پیش

پیاده سازی Control Value Accessor در انگولار


اجزای شناخته شده فرم ها مانند input، checkbox و ... اجزای استانداردی هستند که معمولا مدل پیاده سازی شده ای در کتابخانه هایی مانند angular material دارند. بعضی موقع ها طراح فیلدی طراحی میکنه که با فیلدهای معمول و استاندارد تفاوت داره. پیچیده تره و نیاز به یک کامپوننت خاص داره.

اینترفیس ControlValueAccessor در انگولار به ما این امکان رو میده که با این کامپوننت های خاص مانند یک فیلد فرم ارتباط برقرار کنیم. به کمک CVA میتونیم بین مدیریت فرم و DOM element ها ارتباط برقرار کنیم و رفتارهای فرم مانند یک کامپوننت رو از کامپوننت بالادستش به روشی استاندارد و یکسان پنهان کنیم.

در این مقاله میخوایم یک کامپوننت custom درست کنیم که شامل یک input هست و ControlValueAccessor رو براش پیاده کنیم. چهار بخش برای این مقاله در نظر گرفته شده:

  1. ساخت کامپوننت نمونه
  2. پیاده سازی ControlValueAccessor
  3. اتصال به روش two way binding
  4. اتصال به روش reactive form


قدم اول: ساخت کامپوننت نمونه

اینجا نحوه ساخت و استفاده از کامپوننت های standalone رو کامل توضیح دادم. اگر با کامپونت های standalone آشنایی نداری یا نیازی به مرورشون داری، میتونی مطالعه کنی و ببینی کجا باید این کامپوننت رو برای استفاده معرفی کنی.
اگر نمیخوای از کامپوننت standalone استفاده کنی، یادت باشه که همه import های داخل کامپوننت رو ببری به ngModule مربوطه ش اضافه کنی و کامپوننت رو به لیست declaration های ماژول ngModule اضافه کنی.

با اجرای دستور زیر یک کامپوننت میسازیم به اسم custom input که standalone هست.

داخل src/app یک دایرکتوری ساخته میشه به اسم custom-input:

محتوای فایل custom-input.component.ts به صورت زیر هست:


داخل تمپلت app.component.ts کد زیر رو اضافه میکنیم:

و می بینیم که کامپوننت کار میکنه:


داخل تمپلت کامپوننت ( میتونیم تمپلت رو به خاطر کوچکیش ببریم داخل annotation کامپوننت‌ تعریف کنیم) یک input text تعریف میکنیم:

و خروجی نهایی به صورت زیر مشاهده میشه:

وقتشه بریم سراغ پیاده سازی Value Accessor


قدم دوم: ایجاد دسترسی به VALUE_ACCESSOR

برای اینکه کامپوننت ما بتونه به VALUE_ACCESSOR دسترسی پیدا کنه و بعدا بتونه تمپلت رو آپدیت کنه و ngModel رو bind کنه و مقدار فعلی رو به صورت خروجی بده، داخل component annotation بخش providers تنظیمات لازم رو ست میکنیم:


و بعدش ControlValueAccessor رو پیاده سازی میکنیم. برای این کار نیاز دارید که این متدها و متغیرها رو پیاده سازی کنید:

  1. متد : یک callback function که برای تغییرات UI رجیستر میشود.
  2. متد onTouch : یک callback function که برای تاچ کامپوننت رجیستر میشود.
  3. یک setter بنام value: توسط ngModel استفاده میشود.
  4. متد writeValue: مقدار جدید متغیر را روی element می نویسد.
  5. متد registerOnchange: وقتی value در UI تغییر میکند این متد یک callback function را صدا میکند.
  6. متد registerOnTouch: وقتی المنت در UI تاچ میشود این متد صدا زده میشود.

نحوه پیاده سازی به صورت زیر است:


قدم سوم: اتصال به کامپوننت اصلی به روش Two Way Binding

تا اینجا هیچ اتفاقی نیفتاده! وقتشه قدم آخر رو برداریم و از پیاده سازی استفاده کنیم. در اینجا از روش two way binding و در بخش بعدی از روش Reactive Form استفاده میکنیم.

برای این کار اول FormsModule رو در کامپوننت import میکنیم:

برای کامپوننت هایی که standalone نیستند، این ماژول رو در NgModule مربوطه import میکنیم



بعد تمپلت کامپوننت رو به صورت زیر تغییر میدیم:


داخل app.component.ts یک متغیر تعریف میکنیم تا مقدار مربوط به custom input رو نگهداری کنیم:

اگر لازمه ( قبلا انجام ندادیم ) ماژول NgForms رو به ماژول مربوط به کامپوننت استفاده کننده از custom input اضافه میکنیم. اینجا من به app.module.ts اضافه کردم.

بعد از اضافه کردن متغیر customInput و ماژول NgForms ، به صورت زیر از کامپوننت استفاده میکنیم:

میتونیم یک خروجی هم بگذاریم که نتیجه رو ببینیم:

نتیجه رو میتونیم به راحتی مشاهده کنیم:

قدم چهارم: اتصال به کامپوننت اصلی به روش Reactive Form

تقریبا شبیه قدم قبلیه. اول ماژول ReactiveFormsMudule رو به کامپوننت اضافه میکنیم.

برای کامپوننت هایی که standalone نیستند، این ماژول رو در NgModule مربوطه import میکنیم


بعد یک FormControl به کامپوننت اضافه میکنیم. من اینجا اسمش رو گذاشتم customControl:

این کد رو در NgOnInit یا constructor اضافه میکنیم تا تغییرات costum control رو به بیرون درز بدیم:


حالا custom control رو به input در تمپلت اضافه میکنیم:

وقتشه که توسط FormBuilder یک فرم در کامپوننت استفاده کننده بسازیم:

حالا form control مربوطه رو به کامپوننت مون پاس میدیم:

خروجی مورد نظر ما آماده ست:


نتیجه

الان یک کامپوننت دارم که مثل یک input در فرم رفتار میکنه. حالا در این کامپوننت رفتارهای مورد نظر UI Designer در بخش نمایش به کاربر رو به راحتی پیاده سازی میکنم.

الان چه به روش two way binding و چه به روش reactive form میتونیم فیلدهای خاص طراح رو در سیستم توسعه بدیم.


موفق باشید :)


انگولارangular
۳۰
۵
رهام رفیعی تهرانی
رهام رفیعی تهرانی
برنامه نویسی یک شغل نیست، یک هنره.
شاید از این پست‌ها خوشتان بیاید