نقل البيانات في مكونات Angular الموجهة: أفضل 5 طرق

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

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

ابدأ الدورة

كيفية نقل البيانات في مكونات Angular الموجهة: دليل كامل بلغة TypeScript

\n\n

كل مطور يبدأ العمل مع Angular، عاجلاً أم آجلاً، يواجه سؤالاً: "كيف أنقل البيانات من مكون إلى آخر عبر الموجه؟". على Stack Overflow، جمع هذا السؤال آلاف المشاهدات - وهذا ليس من قبيل الصدفة. على عكس المكونات العادية (parent-child)، حيث يكفي استخدام @Input() و @Output()، يضيف التوجيه في Angular تعقيداته الخاصة.

\n\n

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

\n\n

لماذا لا يمكن ببساطة نقل البيانات عبر @Input؟

\n\n

يحاول العديد من المبتدئين القيام بذلك:

\n\n
// ❌ هذا لا يعمل\n<router-outlet [someData]="data"></router-outlet>
\n\n

يقوم Angular Router بإنشاء المكونات ديناميكيًا. router-outlet هو توجيه (directive)، وليس عنصر قالب. لذلك نقل البيانات مباشرة عبر السمات (attributes) غير ممكن. ولكن هناك طرق بديلة - وهي أكثر ملاءمة!

\n\n

الطريقة 1: استخدام حالة الموجه (Router State) (الأسهل)

\n\n

الطريقة الأكثر بديهية هي نقل البيانات عبر كائن state أثناء التنقل. ظهرت هذه الطريقة في Angular 7+ وتعمل "مباشرة من الصندوق".

\n\n

كيف تعمل

\n\n

تقوم بتمرير كائن بالبيانات عند استدعاء router.navigate() أو عبر routerLink.

\n\n
// المكون A - المرسل\nimport { Component } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n  selector: 'app-user-list',\n  template: `\n    <button (click)="goToDetails()">فتح المستخدم</button>\n  `\n})\nexport class UserListComponent {\n  constructor(private router: Router) {}\n\n  goToDetails() {\n    this.router.navigate(['/user', 42], {\n      state: { name: 'إيفان بيتروف', role: 'admin' }\n    });\n  }\n}
\n\n
// المكون B - المستلم\nimport { Component, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\n\n@Component({\n  selector: 'app-user-details',\n  template: `\n    <div *ngIf="userData">\n      <h2>{{ userData.name }}</h2>\n      <p>الدور: {{ userData.role }}</p>\n    </div>\n  `\n})\nexport class UserDetailsComponent implements OnInit {\n  userData: any;\n\n  constructor(private router: Router) {\n    // الحصول على البيانات من تاريخ التنقل\n    this.userData = this.router.getCurrentNavigation()?.extras?.state;\n  }\n\n  ngOnInit() {\n    // طريقة بديلة - عبر history.state\n    if (!this.userData) {\n      this.userData = history.state;\n    }\n  }\n}
\n\n

الإيجابيات والسلبيات

\n
    \n
  • ✅ سهولة التنفيذ
  • \n
  • ✅ البيانات غير مرئية في URL
  • \n
  • ✅ تعمل مع أي نوع من البيانات (كائنات، مصفوفات)
  • \n
  • ❌ البيانات تُفقد عند تحديث الصفحة
  • \n
  • ❌ لا تعمل عند الانتقال المباشر عبر URL
  • \n
\n\n

متى تستخدم: لنقل البيانات المؤقتة التي ليست حرجة عند إعادة التحميل (مثل رسائل الفلاش، الفلاتر).

\n\n

الطريقة 2: محلل المسار (Route Resolver) (لتحميل البيانات مسبقًا)

\n\n

إذا كنت بحاجة لتحميل البيانات قبل أن يظهر المكون، استخدم Angular Resolver. وهي خدمة تقوم بحل (resolve) البيانات قبل تفعيل المسار.

\n\n

إنشاء Resolver

\n\n
// user.resolver.ts\nimport { Injectable } from '@angular/core';\nimport { Resolve, ActivatedRouteSnapshot } from '@angular/router';\nimport { Observable, of } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class UserResolver implements Resolve<any> {\n  resolve(route: ActivatedRouteSnapshot): Observable<any> {\n    const userId = route.paramMap.get('id');\n    // وم                

المدونات

توصيات الكتب