مدیریت تغییرات ذخیره نشده در انگولار – از صفر تا صد


همه ما با مواردی مواجه شدهایم که قبل از ذخیره کردن برخی تغییرات در یک فرم، به اشتباه دکمه خروج را زدهایم. در این موارد بهترین کار نمایش یک کادر پیام PopUp و پرسش در مورد ضرورت ذخیره تغییرات ذخیره نشده است. در این مقاله در مورد روش مدیریت تغییرات ذخیره نشده در انگولار با استفاده از یک چنین کادری صحبت خواهیم کرد.
برای پیادهسازی چنین کادر پیام بازشوندهای کافی است <wm-can-leave> را در همه صفحههایی که میخواهیم مورد حفاظت قرار گیرند، بگنجانیم. در ادامه شیوه پیادهسازی یک کادر پیام هشداردهنده در مورد تغییرات ذخیره نشده را با هم مرور میکنیم.
هر چه سادهتر، بهتر
در این مقاله از کتابخانه MatDialogModule (+) از Angular Material (+) به عنوان مبنای کار استفاده میکنیم.
اگر با MatDialogModule آشنایی داشته باشید، بخش عمدهای از کد مثال زیر را متوجه میشوید:
تصور کنید کد فوق بخشی از قالب صفحه است که در مورد تغییرات ذخیره نشده، حفاظتی ایجاد میکند. بنابراین به محض این که بخواهید از صفحه خارج شوید، به شرط تعیین شدن متغیر needSave به صورت true، یک کادر محاورهای بازشونده نمایش مییابد که از سوی آن چه درون عنصر <wm-can-leave> قرار دارد، توصیف شده است.
این میتواند یک راهحل عالی برای تضمین کنترل کامل روی محتوای پیام بازشونده باشد، در حالی که کاربرد ساده و شگفتانگیزی نیز دارد. کافی است <wm-can-leave> را در همه صفحههایی که میخواهید مورد حفاظت قرار گیرند، قرار دهید.
پشت صحنه
سلکتور <wm-can-leave> به CanLeaveComponent تعلق دارد که ظرفیتهای یک DialogComponent را ترکیب میکند و بر اساس نشانگرهای یک حفاظت مسیر CanDeactivate نمایش مییابد:
برای تعریف قلابی روی متد حفاظتی CanDeactivate که از سوی روتر انگولار ارائه شده است، کامپوننت متد ()allowDeactivation را از طریق CanLeaveService تزریق شده فراخوانی میکند.
همچنان که در ادامه با بررسی کد سرویس خواهیم دید، ()allowDeactivation یک Observable میپذیرد که در زمان حفاظت از صفحه resolve میشود و با بازگشت دادن مقدار true امکان غیرفعال شدن صفحه را میدهد. در حالی که بازگشت مقدار false مانع این کار خواهد شد.
Observable به نام canLeave$ به این منظور با به تأخیر انداختن ارزیابی ورودی dontLeave امکان نمایش پیام به کاربر را به جای غیرفعال کردن مستقیم فراهم میسازد.
عملگر ()tap به صورت pipe شده تضمین میکند که وقتی غیرفعال شدن انجام یابد، درخواستها در صورت وجود، مورد بررسی قرار میگیرند. این وضعیت به منظور جلوگیری از نمایش چندباره پیام به دلیل نیاز روتر به ریدایرکت کردن کاربر در زمان ترک صفحه طراحی شده است.
حفاظت تعویقی
CanLeaveService حفاظت CanDeactivate را پیادهسازی میکند که بر Observable ارائه شده از سوی CanLeaveComponent تکیه دارد:
پیادهسازی فوق عمومی است و میتوان به روشهای متفاوتی نیز از آن استفاده کرد. مقدار ارسالی همراه با فراخوانی ()allowDeactivation به صورت یک مقدار حفاظتی مناسب از سوی دستگیره ()canDeactivate در زمان مسیریابی مورد استفاده قرار میگیرد.
در این مثال، از مزیت این پیادهسازی برای به تأخیر انداختن نمایش پیام کاربر تا زمان رخداد مسیریابی واقعی استفاده میکنیم.
کادر اعلانی
اگر کنجکاو هستید که بدانید آیا نسخه اعلانی (Declarative) کادر محاورهای که از سوی انگولار ارائه شده را از دست دادهاید، باید بگوییم که نگران نباشید چنین چیزی اصلاً وجود ندارد. کادر ارائه شده از سوی انگولار متریال سرویسی است که باید به صورت دستوری (imperative) استفاده شود. البته این وضعیت موجب میشود همواره فکر کنیم چیزی را از دست دادهایم.
بدین ترتیب برای پر کردن این شکاف میتوان از چیزی مانند زیر استفاده کرد:
ponent شامل یک قالب فرزند تودرتو است که در آن محتوا با استفاده از <ng-content> از والد دریافت میشود. این بدان معنی است که وقتی درون صفحه اعلان شود، قالب دیالوگ کامپایل خواهد شد، اما تا زمانی که بعداً به وسیله منطق MatDialog در زمان فراخوانی ()open رندر نشود، نمایش پیدا نخواهد کرد.
گزینههای زیادی وجود دارند که میتوان برای سفارشیسازی رفتار کادر محاورهای مورد استفاده قرار دارد و همه آنها به صورت یک سری ورودیها روی کامپوننت تعریف شدهاند که بازتابی از مشخصههای MatDialogConfig (+) هستند. کامپوننت یک متد ()open و یک متد ()close ارائه میکند که دومی مقداری دریافت کرده و وضعیت بسته شدن را گزارش میکند.
این کامپوننت همچنین جفتهای ورودی/خروجی opened/openedChange و closed/closedChange را عرضه کرده است که امکان اتصال داده دوطرفه را برای هر دو عملیات باز کردن و بستن کادر محاورهای فراهم میسازد.
محدودیتهای شناخته شده
کامپوننت Dialog محتوای خود را از کانتینر والد میگیرد و از این رو روشی برای عملیاتی کردن دایرکتیو mat-dialog-close وجود ندارد. دلیل این امر آن است که قالبی که باید نمایش یابد، خیلی پیشتر از باز شدن دیالوگ کامپایل شده است و از این رو دایرکتیو ها وهلهسازی شدهاند. یعنی امکان دریافت یک ارجاع دیالوگ معتبر جهت فراخوانی ()close روی آن وجود ندارد.
به طور عکس، قالب دیالوگ درون چارچوب کانتینر والد اجرا میشود و از این رو با استفاده از یک متغیر قالبی به نام ()close میتوانیم به <wm-dilaog> ارجاع دهیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش مقدماتی AngularJS برای ساخت اپلیکیشن های تک صفحه ای
- Lazy Loading در انگولار — به زبان ساده
- ساخت اپلیکیشن انگولار با امکان Drag and Drop — از صفر تا صد
==