אפשר לראות מבנה של ניווט בסיסי בחלק של מודולים.
נראה מבנה של ניווט מתקדם על ידי רכיב טאבים בדף.
תהיה לנו קומפוננטה של טאבים בעמוד הראשי, תחת קומפוננטת Collections מהדרכות קודמות ושלוש קומפוננטות שמכילות את התוכן שאנחנו רוצים להראות בדף בכל פעם שלוחצים על קישור של טאב.
ניצור את הקומפוננטה tabs הראשית ו-3 הקומפוננטות תחת מודול collections.
ng g c collections/tabs
ng g c collections/biography
ng g c collections/companies
ng g c collections/partners
Child Navigation
כרגע יש לנו במודול collections ניווט אחד לעמוד הראשי של המודול.
קובץ collections-routing.module.ts
const routes: Routes = [
{ path: '', component: CollectionsHomeComponent }
];
נוסיף רכיב חדש לניווט הזה של children. על מנת ליצור את הניווט ניבא את הקומפוננטות החדשות שיצרנו.
const routes: Routes = [
{
path: '',
component: CollectionsHomeComponent,
children: [
{ path: '', component: BiographyComponent},
{ path: 'companies', component: CompaniesComponent},
{ path: 'partners', component: PartnersComponent}
]
}
];
את קומפוננטת tabs נוסיף לעמוד הראשי של collections וכדי שתהיה אפשרות לנווט בקןמפוננטת tabs, נוסיף ב-tabs את רכיב הניווט של אנגולר.
קובץ tabs.component.html
<router-outlet></router-outlet>
אפשר לראות שכבר קומפוננטת biography מוצגת בדף.
היחסים בין הקומפוננטות
איך עובד הניווט במערכת אנגולר?
יש לנו את הניווט של app, כשיש מעבר כל קומפוננטה יש לנו טעינה של קומפוננטת הבית של כל קומפוננטה שנטענת.
מכיוון שיש לנו קומפוננטות "ילדים" כדי לבנות את הנתיב, כל נתיב מתווסף לנתיב שנמצא לפניו.
השלב הבא יהיה לבנות את הקוד שמסביב לניווט, במקרה שלנו הקוד של הטאבים.
קובץ tabs.component.html
<app-divider>
Tab Navigation Component
</app-divider>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" routerLink="/collections">Biography</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" routerLink="/collections/companies">Companies</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" routerLink="/collections/partners">Partners</a>
</li>
</ul>
<div class="border bg-light-subtle mt-4 p-3">
<router-outlet></router-outlet>
</div>
Exact Path
יש בעיה כרגע שאם לוחצים על כל טאב, ה-class בשם active נשאר גם ב-טאב הראשון. זה קורה כי הנתיב של הטאב הראשון, שהוא הבסיס, קיים גם בנתיבים של הטאבים האחרים. זה לא מה שאנחנו רוצים שיקרה. לכן נוסיף אפשרות שהנתיב הזה יחשב active רק אם הוא מדוייק.
נוסיף את הקוד [routerLinkActiveOptions]="{exact: true}" לנתיב הראשי.
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}" routerLink="/collections">Biography</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" routerLink="./companies">Companies</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" routerLink="./partners">Partners</a>
</li>
</ul>
קומפוננטה לשימוש רב פעמי
את קומפוננטת ה-tab אנחנו רוצים להפוך לכזו שאפשר להשתמש בה שימוש חוזר. כרגע הקישורים מוכנסים שתוך הקומפוננטה ולא ניתנים לשינוי מבחוץ. אפשר לשלוח לקומפוננטה מערך של קישורים או לכתוב אותם ישירות בתוך הקריאה לקומפוננטה ולהשתמש ב-ng-content.
אני בחרתי להעביר מערך של קישורים מכיוון שזה משאיר את הקוד נקי יותר בצד של המשתמש וקל יותר להבין איך להשתמש בקומפוננטה.
בשביל זה צריך 3 דברים:
- להגדיר משתנה Input בקובץ ה-ts של הקומפוננטה.
- לעבור בלולאה על תוכן המשתנה בקובץ ה-html.
- להעביר את הנתונים בקריאה לקומפוננטה.
שלב 1 – הגדרת המשתנה.
קובץ tabs.component.ts
export class TabsComponent {
@Input() urls: any[] = [];
}
שלב 2 – מעבר בלולאה על התוכן
קובץ tabs.components.html
<ul class="nav nav-tabs">
<li class="nav-item" *ngFor="let objUrl of urls">
<a class="nav-link" routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"
routerLink="{{ objUrl.strUrl }}">{{ objUrl.title }}</a>
</li>
</ul>
<div class="border bg-light-subtle p-3">
<router-outlet></router-outlet>
</div>
שלב 3 – העברת הנתונים
קובץ collections-home.component.ts
export class CollectionsHomeComponent {
urls = [
{strUrl: './', title: 'Biograpy'},
{strUrl: './companies', title: 'Companies'},
{strUrl: './partners', title: 'Partners'}
];
}
קובץ collections-home.component.html
<app-divider>
Tab Navigation Component
</app-divider>
<app-tabs [urls]="urls"></app-tabs>