إذًا، انتهى بنا الأمر إلى حالة “سباق” سيئة بين “الحارس” الذي نستخدمه لاكتشاف متى نحتاج إلى تشغيل إجراء “تحميل المزيد” وعرض الصفوف في دليل المستخدمين ![]()
المشكلة
عندما كان هناك 50 مستخدمًا على الأقل، كانت صفحة /u (دليل المستخدمين) تشغل loadMore فورًا عند التحميل الأول، قبل أن يتمكن المستخدم من التمرير لأسفل. تسبب هذا في تحميل صفحة ثانية غير مرغوب فيها من النتائج تلقائيًا.
السبب الجذري
حالة سباق توقيت أثناء تحميل الصفحة الأولي:
- ينتقل المستخدم إلى
/u - يبدأ
controllers/usersفي تحميل البيانات (isLoading: true) - يتم عرض القالب مع
ConditionalLoadingSpinnerالذي يعرض الدوار - تصل البيانات، وتصبح
isLoadingfalse - يختفي الدوار، ويبدأ
DirectoryTableفي عرض 50 مستخدمًا - يتم إدراج عنصر الحارس
LoadMoreفي DOM - يتم إنشاء
IntersectionObserverويبدأ في المراقبة فورًا - في هذه اللحظة، لا يزال الجدول يحسب التخطيط/يتوسع إلى الارتفاع الكامل
- يظهر الحارس لفترة وجيزة في منفذ العرض (~292 بكسل من الأعلى) قبل أن يتوسع الجدول
- يكتشف المراقب التقاطع → يشغل
loadMore
- يكمل الجدول التوسع إلى الارتفاع الكامل (~3689 بكسل)
- ينتقل الحارس إلى الموضع الصحيح (~3959 بكسل، أسفل منفذ العرض)
كان المراقب “متسرعًا جدًا” - بدأ المراقبة قبل انتهاء المحتوى من تخطيطه، والتقط الحارس خلال اللحظة القصيرة عندما لم يصل الجدول إلى ارتفاعه النهائي بعد.
الإصلاح
تأخير إنشاء المراقب حتى يصبح المحتوى جاهزًا:
تمت إضافة معلمة @isLoading إلى LoadMore تمنع إنشاء IntersectionObserver عندما لا يزال المحتوى قيد التحميل.
كيف يعمل الآن
تحميل الصفحة → isLoading=true → يتخطى المعدل إنشاء المراقب
↓
تحميل البيانات → isLoading=false → يعيد المعدل التشغيل، وينشئ المراقب
↓
الجدول متوسع بالكامل → الحارس في الموضع الصحيح (أسفل منفذ العرض)
↓
يقوم المستخدم بالتمرير لأسفل → يدخل الحارس منفذ العرض → يتم تشغيل loadMore ✓