@HostListner
@HostListner decorator מקשיב לאירועים מה-DOM של האלמנט ומגיב לאירוע על ידי ביצוע של event handler.
בדוגמא נראה איך גורמים ל-div לשנות את המרווחים שלו עם טרנזקציה כשמבוצעת פעולת hover. הפונקציה נעבוד על האלמנט "המארח", כלומר זה שקרא ל-directive.
כשהאירוע mouseenter יקרה באלמנט המארח, הפונקציה onmouseover תתבצע.
בתוך אותו ה-directive אנחנו יכולים להאזין לאירועים נוספים, למשל לאירוע העזיבה של העכבר את האלמנט.
hover.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@HostListener('mouseenter')
onmouseover(){
this.renderer.setStyle(this.element.nativeElement, 'margin', '30px');
this.renderer.setStyle(this.element.nativeElement, 'padding', '10px');
this.renderer.setStyle(this.element.nativeElement, 'transition', '0.5s');
}
@HostListener('mouseleave')
onmouseout(){
this.renderer.setStyle(this.element.nativeElement, 'margin', '10px');
this.renderer.setStyle(this.element.nativeElement, 'padding', '20px');
this.renderer.setStyle(this.element.nativeElement, 'transition', '0.5s');
}
app.component.html
<div appHover>Some content</div>
@HostBinding
@HostBinding מחבר property של אלמנט מארח למשתנה ב-directive.
ניצור property ל-directive בשם background. ל-background נשתמש ב-decorator של @HostBinding. ל-@HostBinding ניתן html property. למשל את ה-property שהגדרנו ב-directive, את ה-background אנחנו רוצים להצמיד ל-property של html שהיא background.
כשאנחנו נקרא ל-directive של appBetterhighlight על אלמנט יש לו תכונה של backgoundColor. ואז אנחנו שמים את הערך transparent לתכונה הזאת.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@HostBinding('style.backgoundColor') background: string = 'yellow';
app.component.html
<div appBetterhighlight>Some content</div>
נקח צעד קדימה ונגיד שאנחנו רוצים שבכל פעם שהגולש עובר מעל ל-div אנחנו רוצים לשנות את הצבע שלו.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@HostBinding('style.backgoundColor') background: string = 'transarent';
@HostListener('mouseenter')
onmouseover(){
this.background = 'pink';
}
@HostListener('mouseleave')
onmouseout(){
this.background = 'transarent';
}
נוסיף עכשיו שינוי של גבול האלמנט.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@HostBinding('style.backgoundColor') background: string = 'transarent';
@HostBinding('style.border') border: string = 'none';
@HostListener('mouseenter')
onmouseover(){
this.background = 'pink';
this.border = 'red 2px solid';
}
@HostListener('mouseleave')
onmouseout(){
this.background = 'transarent';
this.border = 'none';
}
Binding Directive Properties
בדוגמא למעלה השתמשנו בצבעים שכתובים במפורש ב-directive. מה אם אנחנו רוצים לקבל את הצבע מתוך האלמנט עצמו?
ניצור שני משתנים ב-directive שלנו. נחליף את המקומות ששמנו בהם צבעים בערכים של שני שמשתנים האלה.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
defaultColor: string = 'transparent';
highlightColor: string = 'pink';
@HostBinding('style.backgoundColor') background: string = this.defaultColor;
@HostBinding('style.border') border: string = 'none';
@HostListener('mouseenter')
onmouseover(){
this.background = this.highlightColor;
this.border = 'red 2px solid';
}
@HostListener('mouseleave')
onmouseout(){
this.background = this.defaultColor;
this.border = 'none';
}
השלב הבא הוא לקבל את הערכים של המשתנים האלה מתוך האלמנט שקורא ל-directive.
נגדיר את המשתנים כ-Input. עכשיו אנחנו יכולים לחבר את הערכים שלהם לקומפוננטה.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@Input() defaultColor: string = 'transparent';
@Input() highlightColor: string = 'pink';
@HostBinding('style.backgoundColor') background: string = this.defaultColor;
@HostBinding('style.border') border: string = 'none';
@HostListener('mouseenter')
onmouseover(){
this.background = this.highlightColor;
this.border = 'red 2px solid';
}
@HostListener('mouseleave')
onmouseout(){
this.background = this.defaultColor;
this.border = 'none';
}
app.component.html
<div appBetterhighlight [defaultColor]="'yellow'" [highlightColor]="'red'">Some content</div>
הערך ההתחלתי שתקבל התכונה יהיה זה שמוגדר בערך ברירת המחדל ב-directive. כדי להתגבר על זה נגדיר את ngOnInit.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@Input() defaultColor: string = 'transparent';
@Input() highlightColor: string = 'pink';
@HostBinding('style.backgoundColor') background: string = this.defaultColor;
@HostBinding('style.border') border: string = 'none';
ngOnInit(){
this.background = this.defaultColor;
}
@HostListener('mouseenter')
onmouseover(){
this.background = this.highlightColor;
this.border = 'red 2px solid';
}
@HostListener('mouseleave')
onmouseout(){
this.background = this.defaultColor;
this.border = 'none';
}
Direct binding
בדוגמא למעלה אנחנו קוראים ל-directive בתוך אלמנט ה-html ואז שולחים לכל פרמטר את הערך שלו בנפרד.
אפשר לשלוח את הפרמטר ביחד עם השם של ה-directive וזה מתאים במיוחד אם יש לנו חיבור לתכונה אחת שאנחנו רוצים לשנות.
איך עושים את זה?
מקשרים את הפרמטר לשם של ה-directive דרך ה-input.
betterhighlight.directive.ts
constructor(private element: ElementRef, private renderer: Renderer2){}
@Input() defaultColor: string = 'transparent';
@Input('appBetterhighlight') highlightColor: string = 'pink';
@HostBinding('style.backgoundColor') background: string = this.defaultColor;
@HostBinding('style.border') border: string = 'none';
ngOnInit(){
this.background = this.defaultColor;
}
עכשיו נשתמש ישירות ב-directive כדי לשנות את הערך של highlightColor.
app.component.html
<div [appBetterhighlight]="'red'" [defaultColor]="'yellow'">Some content</div>