جاوااسکریپت - چه زمانی باید ng-if را به جای ng-show/ng-hide ترجیح داد؟
من میفهمم که ng-show و ng-hide بر مجموعه کلاسهای یک عنصر تأثیر میگذارند و اینکه ng-if کنترل میکند که آیا یک عنصر به عنوان بخشی از DOM رندر شود یا خیر.
آیا دستورالعملهایی برای انتخاب ng-if نسبت به ng-show/ng-hide یا بالعکس وجود دارد؟
پاسخ شماره ۱
بسته به مورد استفاده شما دارد اما برای خلاصه کردن تفاوت:
ng-ifعناصر را از DOM حذف میکند. این بدان معناست که تمامی هندلرها یا هر چیز دیگری که به آن عناصر متصل شدهاند از بین خواهند رفت. به عنوان مثال، اگر یک هندلر کلیک به یکی از عناصر فرزند متصل کردهاید، وقتیng-ifبه false ارزیابی شود، آن عنصر از DOM حذف خواهد شد و هندلر کلیک شما دیگر کار نخواهد کرد، حتی بعد از اینکهng-ifبعداً به true ارزیابی شد و عنصر را نمایش داد. شما باید هندلر را دوباره متصل کنید.ng-show/ng-hideعناصر را از DOM حذف نمیکند. این از استایلهای CSS برای پنهان/نمایش عناصر استفاده میکند (توجه: ممکن است نیاز باشد کلاسهای خود را اضافه کنید). به این ترتیب، کنترلکنندههایی که به فرزندان متصل شدهاند از بین نخواهند رفت.ng-ifیک محدوده فرزند ایجاد میکند در حالی کهng-show/ng-hideاین کار را نمیکند
عناصری که در DOM نیستند کمتر بر عملکرد تاثیر میگذارند و ممکن است برنامه وب شما هنگام استفاده از ng-if نسبت به ng-show/ng-hide سریعتر به نظر برسد. تجربه من نشان میدهد که تفاوت قابل توجهی ندارد. انیمیشنها هم هنگام استفاده از ng-show/ng-hide و هم ng-if امکانپذیر هستند، با مثالهایی برای هر دو در مستندات Angular.
در نهایت، سوالی که باید به آن پاسخ دهید این است که آیا میتوانید المان را از DOM حذف کنید یا نه؟
پاسخ شماره ۲
برای مشاهده یک CodePen که تفاوت عملکرد ng-if/ng-show را از نظر DOM نشان میدهد، اینجا را ببینید.
@markovuksanovic به خوبی به سؤال پاسخ داده است. اما من از زاویه دیگری به آن نگاه میکنم: من همیشه از ng-if استفاده میکنم و آن عناصر را از DOM خارج میکنم، مگر اینکه:
- شما به ناظران دادهcها و
$watchهای روی عناصر خود نیاز دارید تا زمانی که به دلایل خاصی پنهان هستند فعال بمانند. اگر میcخواهید بتوانید ورودیcهایی را که در حال حاضر قابل مشاهده نیستند تأیید کنید تا مشخص شود که آیا کل فرم معتبر است یا خیر، فرمcها میcتوانند مثال خوبی برای این موضوع باشند. - شما از یک منطق حالتی واقعاً پیچیده با هندلرهای رویدادی شرطی استفاده میکنید، همانطور که در بالا اشاره شد. با این حال، اگر متوجه میشوید که هندلرها را بهطور دستی ضمیمه و جدا میکنید، بهطوری که هنگام استفاده از ng-if وضعیت مهمی را از دست میدهید، از خود بپرسید آیا آن وضعیت بهتر است در یک مدل داده نمایش داده شود، و هندلرها به طور شرطی توسط دایرکتیوها هر زمان که عنصر نمایش داده میشود اعمال شوند. به عبارت دیگر، حضور/عدم حضور هندلرها نوعی داده وضعیت است. آن داده را از DOM خارج کرده و به مدل منتقل کنید. حضور/عدم حضور هندلرها باید توسط دادهها تعیین شود و بنابراین بازتولید آنها آسان باشد.
انگولار واقعاً به خوبی نوشته شده است. با توجه به کاری که انجام میدهد، سریع است. اما کاری که انجام میدهد یک عالمه جادو است که چیزهای سخت (مثل اتصال داده دوطرفه) را trivially ساده نشان میدهد. ساده نشان دادن همه این چیزها باعث افزایش بار عملکردی میشود. ممکن است شوکه شوید وقتی متوجه شوید که یک تابع setter صدها یا هزاران بار در طول چرخه $digest بر روی بخشی از DOM که هیچکس حتی به آن نگاه نمیکند، ارزیابی میشود. و سپس متوجه میشوید که دهها یا صدها عنصر نامرئی همه همان کار را انجام میدهند...
کامپیوترهای رومیزی ممکن است واقعاً به اندازه کافی قدرتمند باشند تا بیشتر مشکلات سرعت اجرای JS را بیاثر کنند. اما اگر برای موبایل توسعه میدهید، استفاده از ng-if هر زمان که به طور انسانی ممکن است، باید واضح باشد. سرعت JS هنوز روی پردازندههای موبایل اهمیت دارد. استفاده از ng-if یک راه بسیار آسان برای به دست آوردن بهینهسازی بالقوه مهم با هزینهای بسیار، بسیار کم است.
پاسخ شماره ۳
از تجربه من:
1) اگر صفحه شما یک سوئیچ دارد که از ng-if/ng-show برای نمایش/پنهان کردن چیزی استفاده میکند، ng-if باعث تأخیر بیشتری در مرورگر میشود (کندتر است). برای مثال: اگر شما یک دکمه دارید که برای تغییر بین دو نما استفاده میشود، به نظر میرسد ng-show سریعتر است.
2) ng-if هنگام ارزیابی به true/false اسکوپ ایجاد/حذف میکند. اگر کنترلری به ng-if متصل باشد، کد آن کنترلر هر بار که ng-if به true ارزیابی شود اجرا خواهد شد. اگر از ng-show استفاده کنید، کد کنترلر فقط یک بار اجرا میشود. بنابراین، اگر دکمهای داشته باشید که بین چندین نما جابجا میشود، استفاده از ng-if و ng-show تفاوت بزرگی در نحوه نوشتن کد کنترلر شما ایجاد میکند.
پاسخ شماره ۴
پاسخ ساده نیست:
این بستگی به دستگاههای هدف دارد (موبایل در مقابل دسکتاپ)، بستگی به ماهیت دادههای شما، مرورگر، سیستم عامل، سختافزاری که روی آن اجرا میشود دارد... اگر واقعاً میخواهید بدانید، باید آزمایش مقایسهای انجام دهید.
این عمدتاً یک مشکل حافظه در مقابل محاسبات است ... همانند بیشتر مسائل عملکردی، تفاوت میتواند با عناصر تکراری (n) مانند لیستها، به ویژه زمانی که تو در تو باشند (n x n، یا بدتر) و همچنین نوع محاسباتی که داخل این عناصر انجام میدهید، قابل توجه شود:
ng-show: اگر آن عناصر اختیاری اغلب موجود باشند (متراکم)، مثلاً حدود ۹۰٪ از اوقات، ممکن است سریعتر باشد که آنها را آماده داشته باشیم و فقط نمایش/مخفی کنیم، مخصوصاً اگر محتوای آنها ساده باشد (فقط متن ساده، هیچ چیزی برای محاسبه یا بارگذاری نیست). این حافظه مصرف میکند زیرا DOM را با عناصر مخفی پر میکند، اما فقط نمایش/مخفی کردن چیزی که قبلاً وجود دارد احتمالاً برای مرورگر عملیاتی کمهزینه است.
ng-if: اگر برعکس، احتمال اینکه عناصر نمایش داده نشوند زیاد باشد (پراکنده)، فقط آنها را بسازید و در زمان واقعی نابود کنید، بهویژه اگر محتوای آنها دریافت آن گران باشد (محاسبات/مرتبسازی/فیلتر، تصاویر، تصاویر تولیدشده). این برای عناصر نادر یا «در صورت نیاز» ایدهآل است، زیرا در صرفهجویی حافظه از نظر پر نکردن DOM کمک میکند اما میتواند هزینه محاسبات زیادی داشته باشد (ایجاد/نابود کردن عناصر) و پهنای باند (دریافت محتوای راه دور). همچنین به این بستگی دارد که چقدر در نما محاسبه میکنید (فیلتر/مرتبسازی) نسبت به آنچه که در مدل از قبل دارید (دادههای از قبل مرتبشده/فیلترشده).
پاسخ شماره ۵
یک نکته مهم:
ngIf (برخلاف ngShow) معمولاً اسکوپهای فرزند ایجاد میکند که ممکن است نتایج غیرمنتظرهای به همراه داشته باشند.
من یک مسئله مربوط به این داشتم و زمان زیادی را صرف کردم تا بفهمم چه اتفاقی میافتد.
(دستور من مقادیر مدل آن را در محدوده نادرست مینوشت.)
پس، برای حفظ موهای خود از ngShow استفاده کنید، مگر اینکه خیلی آهسته اجرا شوید.
به هر حال تفاوت عملکرد به سختی قابل مشاهده است و من هنوز مطمئن نیستم که به نفع چه کسی است بدون آزمایش...