Angular 2 التمرير إلى الأعلى عند تغيير المسار: حل للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Angular 2 التمرير إلى الأعلى عند تغيير المسار: لماذا هو مهم وكيفية تنفيذه

\n\n

تخيل أنك تتصفح صفحة طويلة من الوثائق، وتصل إلى المنتصف، ثم تنقر على رابط - وتجد نفسك في أسفل قسم جديد. هل هذا مألوف؟ هذه هي المشكلة التي يحلها ميكانيك Angular 2 التمرير إلى الأعلى عند تغيير المسار. بدونها، تتأثر تجربة المستخدم: يضطر المستخدم إلى التمرير يدويًا باستخدام عجلة الفأرة أو الضغط على زر Home، مما يسبب الإزعاج ويزيد من معدل الارتداد.

\n\n

في هذه المقالة، سنشرح كيفية جعل Angular يقوم تلقائيًا بتمرير الصفحة إلى الأعلى عند كل انتقال بين المسارات. ستتعلم ليس فقط الحل الجاهز، بل ستفهم أيضًا لماذا يعمل بهذه الطريقة. المقالة مكتوبة للمبتدئين، ولكنها ستكون مفيدة أيضًا للمطورين ذوي الخبرة الذين يرغبون في تحديث معرفتهم.

\n\n

لماذا لا يقوم Angular بذلك "افتراضيًا"؟

\n\n

Angular هو إطار عمل قوي لتطبيقات الصفحة الواحدة (SPA)، ولكن سلوكه أثناء التنقل قد يكون مفاجئًا. افتراضيًا، عند تغيير المسار، لا يعيد المتصفح تعيين موضع التمرير. لماذا؟ لأن Angular Router يعتبر الانتقال بمثابة استبدال المكون في <router-outlet>، وليس تحميل صفحة جديدة. بينما يعتقد المتصفح: "ما زلت في نفس المستند، لماذا يجب أن أتمرر؟".

\n\n

هذا ملحوظ بشكل خاص إذا كان لديك قوائم طويلة أو جداول أو وثائق. ينقر المستخدم على رابط في أسفل الصفحة - ويتم فتح المحتوى الجديد، لكن التمرير يبقى في الأسفل. حل هذه المشكلة هو إخبار Angular بوضوح: "مرحبًا، عند كل انتقال، قم بالتمرير إلى الأعلى!".

\n\n

طريقتان للحل

\n\n

هناك طريقتان رئيسيتان لتنفيذ التمرير إلى الأعلى عند تغيير المسار في Angular 2+:

\n\n
    \n
  • معالج عام في AppComponent - بسيط، لكنه لا يعمل دائمًا بشكل صحيح مع المسارات المتداخلة.
  • \n
  • استخدام تكوين المسار (Route Config) - أكثر مرونة، ويسمح بتخصيص السلوك لكل مسار على حدة.
  • \n
\n\n

سننظر في كليهما، لكنني أوصي بالتركيز على الثاني - فهو يمنحك تحكمًا أكبر.

\n\n

الطريقة 1: معالج عام بسيط (لبداية سريعة)

\n\n

افتح ملف app.component.ts (أو المكون الجذري) وأضف اشتراكًا في أحداث Router. الكود بلغة TypeScript:

\n\n
\nimport { Component, OnInit } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n  styleUrls: ['./app.component.css']\n})\nexport class AppComponent implements OnInit {\n  constructor(private router: Router) {}\n\n  ngOnInit() {\n    this.router.events.pipe(\n      filter(event => event instanceof NavigationEnd)\n    ).subscribe(() => {\n      window.scrollTo(0, 0);\n    });\n  }\n}\n
\n\n

هنا، نشترك في أحداث الموجه، ونقوم بتصفية NavigationEnd فقط (لحظة اكتمال الانتقال)، ثم نستدعي window.scrollTo(0, 0). الأمر بسيط، لكن هناك فارق بسيط: إذا كان لديك مسارات متداخلة (مثل مسارات فرعية داخل مكون)، فقد يتم تشغيل هذا الكود مبكرًا جدًا أو لا يتم تشغيله على الإطلاق.

\n\n

الطريقة 2: الحل الصحيح باستخدام تكوين المسار (موصى به)

\n\n

يستخدم هذا الأسلوب الخيار المدمج scrollPositionRestoration في Angular Router. بدءًا من Angular 6.1، أصبح من الممكن تكوين الاستعادة/إعادة التعيين التلقائي للتمرير مباشرة في تكوين التوجيه.

\n\n

افتح ملف app-routing.module.ts وأضف الخيار scrollPositionRestoration: 'top' في RouterModule.forRoot():

\n\n
\nimport { NgModule } from '@angular/core';\nimport { RouterModule, Routes } from '@angular/router';\n\nconst routes: Routes = [\n  { path: '', component: HomeComponent },\n  { path: 'about', component: AboutComponent },\n  { path: 'contact', component: ContactComponent }\n];\n\n@NgMod                

المدونات

توصيات الكتب