נתחיל במה זה Directive
ההגדרה הכי פשוט לזה היא: פונקציה שמופעלת על כל רכיב HTML שאנחנו מסמנים על ידי מאפיין.
directive יכול לשנות צבע של תגית והוא יכול לשנות את מבנה ה-DOM, הכל בהתאם למה שאנחנו רוצים.
אנחנו משתמשים בהם די הרבה בפרויקט אנגולר כמו: ngFor, ngIf, ngClass ……
כאשר אנחנו מיצרים דיירקטיב עדיף לתת לפני השם שלו איזו שהיא מילה שתיחד אותו ותשייך אותו אלינו,
כמובן לא לבחור ב-ng , זה שמור לאנגולר ויכול לגרום להתנגשות.
אם החלטנו לעשות IF חדש, אז אנחנו יכולים לקרוא לו my-if ולא ng-if.
כמובן שדיירקטיב יכול לקבל ולהוציא מידע בדיוק כמו רכיב ומיד אראה איך.
בדוגמה אראה איך לעשות tooltip בעזרת directive
import { ContentChild, Directive, ElementRef, HostListener, Input, Output, Renderer2, TemplateRef, ViewContainerRef, EventEmitter } from '@angular/core'; @Directive({ selector: '[appTooltip]' }) export class TooltipDirective { @Output() isWorking: EventEmitter<boolean> = new EventEmitter<boolean>(); constructor( private renderer: Renderer2, private elementRef: ElementRef, private viewContainerRef: ViewContainerRef) { } @ContentChild("tooltip") private tooltipTemplateRef: TemplateRef<Object>; @HostListener('mouseenter') onMouseEnter(): void { this.showTooltip(); } @HostListener('focus') onFocus(): void { this.showTooltip(); } @HostListener('mouseleave') onMouseLeave(): void { this.hideTooltip(); } @HostListener('blur') onBlur(): void { this.hideTooltip(); } showTooltip() { const view = this.viewContainerRef.createEmbeddedView(this.tooltipTemplateRef); view.rootNodes.forEach(node => this.renderer.appendChild(this.elementRef.nativeElement, node)); this.isWorking.emit(true); } hideTooltip() { if (this.viewContainerRef) { this.viewContainerRef.clear(); } this.isWorking.emit(false); } }
בקצרה:
יצרנו דיירקטיב עם קידומת app כדי ליחד אותו כרכיב שלנו ולא של אנגולר.
מבוצע חיפוש בתוך אותו רכיב לתגית שיש לה את המאפיין tooltip וביצוע של השמה או מחיקה של הרכיב הזה מה-DOM.
התנאים שאנחנו מפעילים לביצוע הפעולה הם :
- עכבר נכנס
- עכבר יוצר
- הרכיב מקבל פוקוס
- הרכיב מאבד פוקוס
כאשר הפונקציות מופעלות, הדיירקטיב מוציא מידע לרכיב העוטף של true או false .
את העיצוב של ה-tooltip שמתי ב-style.css הכללי של הפרויקט כדי להשפיע עליו אותו דבר בכל מקום בפרויקט שלנו.
[appTooltip] { position: relative; } .tooltip { position: absolute; bottom: 100%; left: 0; padding: 10px; background: #fff; box-shadow: 0 2px 1px rgba(0,0,0,.6); }
עכשיו נעבור לראות איך זה נראה ברכיב עצמו
<div appTooltip (isWorking)="onTooltip($event)" tabindex="0"> <p [ngClass]="{'toolTipOn':tooltipShow}">first-component works!</p> <ng-template #tooltip> <div class="tooltip"> <span>HI I AM TOOLTIP</span> </div> </ng-template> </div>
.toolTipOn { background-color: aquamarine; font-weight: bold; }
export class FirstComponentComponent implements OnInit { public tooltipShow: boolean; constructor() { } ngOnInit(): void { } onTooltip(event) { this.tooltipShow = event; } }
כפי שאפשר לראות, לקחנו DIV רגיל והוספנו לו את הדיירקטיב appTooltip ולכן יכלנו גם להוסיף את ה-OUTPUT שלנו למרות של-DIV אין מאפיין כזה.
יצרנו משתנה tooltipShow ופונקציה onTooltip שמקבלת את ה-EMIT ומיישמת אותו על המשתנה. זה גורם ל-NGCLASS להגיב ולהוסיף או למחוק CSS CLASS בשם tooltipOn.
הגדרנו ב-CSS של הרכיב, פרמטרים של צבע רקע והדגשה של הטקסט.
התוצאה הסופית היא שכל פעם שה-tooltip מופעל אז הטקסט של אותה תגית משנה את הצבע והמשקל שלו.