שימוש רב פעמי לקומפוננטות

יתרון משמעותי לקומפוננטות הוא השימוש החוזר בהן בתוך האפליקציה ומחוץ לה.

הוספת מודל חדש

כדי לעבוד עם החלק הזה נעבור לקומפוננטה בשם Mods ששיכת לתוכנית שעליה עובדים בחלקים האחרונים. קומפוננטת הבסיס תהיה ModsHome. ניצור את הקומפוננטה הראשית בתיקיית mods. בנוסף ניצור את קומפוננטת modal שאיתה נעבוד.

ng g c mods/ModsHome
ng g c mods/Modal

נוסיף את הנתיב של קומפוננטת Modal בקובץ routing של מודל Mods.

קובץ mods-routing.modules.ts

const routes: Routes = [
  { path: '', component: ModsHomeComponent }
];

נוסיף בקובץ הניווט הראשי את הנתיב של mods.

קובץ app-routing.modules.ts

const routes: Routes = [
  {
    path: 'elements',
    loadChildren: () =>
      import('./elements/elements.module').then(m => m.ElementsModule)
  },
  {
    path: 'collections',
    loadChildren: () =>
      import('./collections/collections.module').then(m => m.CollectionsModule)
  },
  {
    path: 'mods',
    loadChildren: () =>
      import('./mods/mods.module').then(m => m.ModsModule)
  },
  { path: '', component: HomeComponent },
  { path: '**', component: NotFoundComponent }
];

עכשיו נציג את modals בקומפוננטת ModsHome.

קובץ mods-home.component.html

<app-divider>Modal Component</app-divider>

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Launch demo modal
</button>

<app-modal></app-modal>

יש לנו קומפוננטת כותרת כללית, נייבא אותה למודול Mods כדי להשתמש בה ונוסיף את הכפתור שפותח את התיבה.

** כדי שקוד javascript של Bootstrap יעבוד צריך לראות שהוספנו את הנתיב אליו בקובץ angular.json תחת מערך scripts.

לקומפוננטה modal נוסיף חלון קופץ של bootstrap עם כפתור שמקפיץ אותו.

קובץ modal.component.html

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

בקובץ ה-class נוסיף את האלמנט לעץ של קובץ ה-html.

קובץ modal.component.ts

export class ModalComponent implements OnInit {
  constructor(private el: ElementRef){
  }

  ngOnInit(){
    document.body.appendChild(this.el.nativeElement);
  }
}

יש לנו בעיה, שאם פותחים את החלון הקופץ ולוחצים על כפתור "חזור" בדפדפן, החלון לא נסגר לגמרי והמסך נשאר שחור. צריך להרוס את האלמנט כשיוצאים מהקומפוננטה.

חוץ מזה הורדתי ידנית את הרקע השחור שמופיע עם עליית המודל, מכיוון שגם בהריסת האלמנט, משום מה bootstrap משאירים את הרקע השחור.

קובץ modal.component.ts

export class ModalComponent implements OnInit, OnDestroy {
  constructor(private el: ElementRef){
  }

  ngOnInit(){
    document.body.appendChild(this.el.nativeElement);
  }

  ngOnDestroy(){
    this.el.nativeElement.remove();
    document.getElementsByClassName('modal-backdrop')[0].classList.remove('show');
  }
}

באירוע הסגירה שך המודל, bootstrap כבר מטפלים בשבילנו.

שימוש חוזר בקומפוננטת מודל

עכשיו אנחנו רוצים שאפשר יהיה להשתמש בקומפוננטה הזאת מכל מקום באפליקציה שלנו. נוסיף את ng-content למקום התוכן של המודל. את התוכן הזה יהיה אפשר לשלוח בזמן הקריאה לקומפוננטה.

נוסיף גם אלמנט שיתן את הכותרת של התיבה.

גם הכפתורים צריכים להיות מותאמים, ולכן נוציא אותם ה-content בשם modalFooter. בנוסף, כדי לא להציג את הפוטר אם אין בו תוכן, נוסיף בקובץ ה-css הוראה לא להראות את כל החלק של הפוטר אם הוא ריק.

קובץ modal.component.html

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="exampleModalLabel"><ng-content select="[modalTitle]"></ng-content></h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <ng-content></ng-content>
      </div>
      <div class="modal-footer">
        <ng-content select="[modalFooter]"></ng-content>
      </div>
    </div>
  </div>
</div>

קובץ mods-home.component.html

<app-modal>
  <span modalTitle>Title of the modal</span>
  Reusable modal content.
  <ng-container modalFooter>
    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
    <button type="button" class="btn btn-primary">Save changes</button>
  </ng-container>
</app-modal>

קובץ modal.component.css

.modal-footer:empty{
  display: none;
}

באותה הדרך ניתן לבנו קומפוננטות נוספות, לעצב אותן, לתת להן פונקציונליות ולהכין אותן לשימוש חוזר באפליקציה.

ניווט במאמר

מאמרים אחרונים

Weekly Tutorial