فریمورک انگولار یکی از قدرتمندترین و محبوبترین فریمورکهای توسعه وب برای ایجاد برنامههای تکصفحهای (Single Page Application) است. یکی از چالشهای اصلی در توسعه برنامههای پیچیده با برنامه انگولار مدیریت وضعیت برنامه است. این وضعیت معمولا شامل دادههای کاربر، وضعیت نمایشی صفحه، تنظیمات و سایر اطلاعاتی است که در طول زمان در برنامه تغییر میکند.
برای مقابله با این چالش و مدیریت بهتر وضعیت در پروژهی انگولار ایجاد شده، Ngrx راه حل است، این کتابخانه الهام گرفته از Redux است که باعث سادهتر و موثرتر شدن مدیریت وضعیت برنامه در انگولار میشود.
مفهوم Ngrx یک کتابخانه مدیریت وضعیت (state management) در انگولار است که به شما کمک میکند وضعیت برنامهی خود را به صورت مرتب و مدیریتشدهای نگه دارید. به طور خلاصه، اصل این کتابخانه بر پایه الگوی Redux است که به شما امکان میدهد تغییرات در برنامه را به صورت قابل پیشبینی و یکطرفه (unidirectional) مدیریت کنید.
حالا بیایید با مثالی ساده توضیح دهم:
تصور کنید که شما یک برنامه انگولار ساده دارید که یک شمارنده (counter) دارد. این شمارنده را میتوانید با دکمههای "افزایش"، "کاهش" و "صفر کردن" تغییر دهید.
بدون Ngrx : وقتی از مدیریت وضعیت بدون Ngrx استفاده میکنید، شمارنده به صورت مستقیم در کامپوننت شما ذخیره میشود. هربار که کاربر دکمه "افزایش" را میزند، مقدار شمارنده افزایش پیدا میکند و همینطور برای دکمههای "کاهش" و "صفر کردن". اگر بخواهید این وضعیت را به کامپوننتهای دیگر منتقل کنید، باید از ورودیها و خروجیها استفاده کنید و این میتواند باعث پیچیدگی و دردسرهای مدیریتی شود، به ویژه اگر برنامهی شما بزرگتر و پیچیدهتر شود.
با استفاده از Ngrx : وقتی ازNgrx استفاده میکنید، شمارنده به عنوان یک وضعیت مرکزی (centralized state) درون یک فروشگاه (store) ذخیره میشود. این فروشگاه یک منبع تکی از حقیقت (single source of truth) است که وضعیت کامل برنامه را نگهداری میکند. هربار که کاربر دکمه افزایش را میزند، یک عملیات (action) به فروشگاه ارسال میشود که به آن میگوید شمارنده را افزایش بده. سپس، تغییر در وضعیت اعمال میشود تا مقدار شمارنده در فروشگاه بهروز شود. همین روند برای دکمههای کاهش و صفر کردن نیز صادق است.
مزیت اصلی استفاده از Ngrx این است که شما میتوانید وضعیت برنامهی خود را از یک مکان مرکزی مدیریت کنید. این کتابخانه شما را از پیچیدگیهای مدیریتی خلاص میکند و باعث میشود که بتوانید به راحتی تغییرات در وضعیت برنامه را پیشبینی و ردیابی کنید. همچنین، به شما امکان میدهد تغییراتی که در وضعیت اتفاق میافتد را ثبت کنید و تاریخچهی تغییرات را در نظر بگیرید، که این میتواند برای اشکالزدایی (debugging) کاربردی باشد.
با این وجود، استفاده از Ngrx برای برنامههای کوچک و ساده ممکن است یک کم بیش از حد پیچیده به نظر بیاید، اما برای برنامههای بزرگ و پیچیده که دارای وضعیت واحد یا اطلاعات مشترکی هستند، این ابزار میتواند بسیار مفید و کمک کننده باشد.
مثال ۱: مدیریت وضعیت لیست کارها (Todo List) :
تعریف عملیاتها: در این مرحله، عملیاتهای مورد نیاز برای مدیریت لیست کارها را تعریف میکنیم. عملیاتها مثل "افزودن کار جدید"، "حذف کار" و "تغییر وضعیت کار" از این دست هستند.
تعریف وضعیت اولیه و ایجاد reducer: ما یک وضعیت اولیه برای لیست کارها ایجاد میکنیم و یکreducer تعریف میکنیم که وضعیتها را بر اساس اقدامات اعمال شده بروز میدهد.
مثال ۲: مدیریت وضعیت نمایش یا عدم نمایش دکمه
تعریف عملیاتها: در این مرحله، عملیاتهای مورد نیاز برای مدیریت وضعیت نمایش یا عدم نمایش دکمه را تعریف میکنیم. عملیاتها مثل "نمایش دکمه" و "عدم نمایش دکمه" از این دست هستند.
تعریف وضعیت اولیه و ایجاد reducer: ما یک وضعیت اولیه برای نمایش یا عدم نمایش دکمه ایجاد میکنیم و یکreducer تعریف میکنیم که وضعیتها را بر اساس اقدامات اعمال شده بروز میدهد.
در تکه کد بالا برای ایجاد سه اکشن showButton و hideButton نیاز هست فانکشن createAction را از کتابخانه ی Ngrx ایمپورت کنیم و سپس نام یک اکشن را به صورت یک رشته به عنوان ورودی به این فانکشن بدهیم.
فانکشن createReducer را از کتابخانهی Ngrx ایمپورت کرده و سپس به عنوان اولین آرگومان ورودی حالت اولیه برنامه را در نظر میگیرم و با on میتوان تغییراتی را هر اکشن لازم است در وضعیت برنامه ایجاد کند را اعمال کرده و یا اطلاعاتی که از وضعیت برنامه نیاز دارد را ستخراج کند.
در تکه کد بالا برای ایجاد سه اکشن Add Todo و Remove Todo و Toggle Todo نیاز هست در ابتدا فانکشن createAction را از کتابخانه ی Ngrx ایمپورت کنیم و سپس نام یک اکشن را به صورت یک رشته به عنوان ورودی به این فانکشن بدهیم.
فانکشن createReducer را از کتابخانهی Ngrx ایمپورت کرده و سپس به عنوان اولین آرگومان ورودی حالت اولیه برنامه را در نظر میگیرم و با on میتوان تغییراتی را هر اکشن لازم است در وضعیت برنامه ایجاد کند را اعمال کرده و یا اطلاعاتی که از وضعیت برنامه نیاز دارد را ستخراج کند.
مدیریت وضعیت برنامه: وقتی برنامهها بزرگ و پیچیده میشوند، وضعیت آنها نیز پیچیده میشود. با استفاده از Ngrx، میتوانید تمامی وضعیتهای برنامه را در یک مکان مرکزی ذخیره کنید و تغییرات آنها را به صورت قابل پیشبینی و یکطرفه اعمال کنید.
مدیریت دادهها و اطلاعات مشترک: وقتی که بیش از یک کامپوننت به یک مجموعه از دادهها نیاز دارند، استفاده از Ngrx میتواند بسیار مفید باشد. این کتابخانه به شما امکان میدهد تا دادههای مشترک و مهم بین کامپوننتها را در یک فروشگاه (store) مدیریت کنید.
استفاده از Side Effects : این کتابخانه Ngrx دارای افکتها (effects) است که برای مدیریت اعمال جانبی مانند درخواستهای API و انجام عملیاتهای غیرهمگام استفاده میشود. این افکتها از اینکه عملیاتهای محاسباتی و طولانی مدت که باید به صورت غیرهمگام انجام شوند، راحتتر میکنند.
اشتراک اطلاعات بین برنامهها: اگر برنامه شما بیش از یک برنامه کوچک (sub-applications) دارد که باید به صورت مستقل و با دیگر برنامهها ارتباط برقرار کنند، میتوانید ازNgrx برای اشتراک اطلاعات بین این برنامهها استفاده کنید.
این کتابخانه ازTime-Travel Debugging پشتیبانی میکند که به شما امکان میدهد تغییرات در وضعیت برنامه را در طول زمان پیگیری کنید و مشکلاتی که به وقوع پیوستهاند را پیدا کنید.
نتیجه گیری:
مانند هر مفهوم دیگری در برنامه نویسی Ngrx دارای مزایا و معایبی است و زمانی که در جای درست خود به کار برده شود از مزایای آن برخوردار خواهیم شد. برای مثال های ارائه شده در این مقاله می توان از دکوراتورهای @Input ,@Output به سادگی استفاده کرد و یا از سرویس ها بهره برد و درگیر پیچیدگی های مربوط به Ngrx نشد.
مهم است بدانید کهNgrx مناسب برنامههای بزرگتر و پیچیدهتر است و برای برنامههای کوچک و ساده ممکن است بیش از حد اجباری و پیچیده به نظر بیاید. همچنین، مدیریت وضعیت با استفاده از Ngrx نیازمند مدیریت مناسب و تجربه برنامهنویسی مناسب است، بنابراین قبل از استفاده از آن در پروژههای خود، به دقت تصمیمگیری کنید که آیا واقعاً نیازمندیهای پیچیده و مدیریت وضعیت مرکزی دارید یا خیر.
در این لینک گیتهاب میتوانید یک مثال از نحوهی استفاده از کتابخانهی Ngrx را در یک پروژه ی انگولاری ببینید. این مثال برای یک شمارنده و دارای سه اکشن برای افزایش و کاهش مقدار شمارنده و همچنین صفر کرن مقدار شمارنده است.
گردآورندگان مقاله: هوتن همتی و زهرا رضائی