10. Attribute Directives
Simple Attribute Directive:
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = '#ff6666';
el.nativeElement.style.color = '#ffffff';
}
}
AppComponent:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>{{ title }}</h1>
<div class="left">
<h2>My First Love Attribute Directive</h2>
<p myHighlight>My polymer princess: I ❤ you!</p>
</div>
<div class="right">
<img [src]="imageUrl" class="img-round" alt="princess image">
</div>
`,
styles: ['h1 { font-weight: bold; }']
})
export class AppComponent {
title = 'Tour of Technologies';
imageUrl = '../assets/polymer1.jpg-large';
}
Let's have a look at this beauty in our Chromium Web Browser:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
@Input('myHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.initial();
}
constructor(private el: ElementRef) {
this.initial();
}
private initial() {
this.el.nativeElement.style.backgroundColor = '#ff6666';
this.el.nativeElement.style.color = '#ffffff';
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
AppComponent:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>{{ title }}</h1>
<div class="left">
<h2>My First Love Attribute Directive</h2>
<p [myHighlight]="color">My polymer princess: I ❤ you!</p>
</div>
<div class="right">
<img [src]="imageUrl" class="img-round" alt="princess image">
</div>
`,
styles: ['h1 { font-weight: bold; }']
})
export class AppComponent {
title = 'Tour of Technologies';
imageUrl = '../assets/polymer1.jpg-large';
color = '#ff1a1a';
}
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<h1>{{ title }}</h1>
<div class="left">
<h2>My First Love Attribute Directive</h2>
<h4>Pick a highlight color</h4>
<div>
<input type="radio" name="colors" (click)="color='red'">red
<input type="radio" name="colors" (click)="color='blue'">blue
<input type="radio" name="colors" (click)="color='green'">green
<input type="radio" name="colors" (click)="color='yellow'">yellow
</div>
<p [myHighlight]="color">My polymer princess: I ❤ you!</p>
<p [myHighlight]="color" defaultColor="violet">My polymer princess: I ❤ you so much!!!</p>
</div>
<div class="right">
<img [src]="imageUrl" class="img-round" alt="princess image">
</div>
`,
styles: ['h1 { font-weight: bold; }']
})
export class AppComponent {
title = 'Tour of Technologies';
imageUrl = '../assets/polymer1.jpg-large';
color: string;
}
Updated HighlightDirective:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
@Input('myHighlight') highlightColor: string;
@Input() defaultColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || this.defaultColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.initial();
}
constructor(private el: ElementRef) {
this.initial();
}
private initial() {
this.el.nativeElement.style.backgroundColor = '#ff6666';
this.el.nativeElement.style.color = '#ffffff';
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
Let's view the results in Chromium:
NgClass:
import { Component } from '@angular/core';
@Component({
selector: 'app-love',
template: `
<i class="fa fa-2x red"
[ngClass]="{
'fa-heart': isSelected,
'fa-heart-o': !isSelected
}"
(click)="onToggle()"
aria-hidden="true"></i>
`,
styles: [ `.red { color: red; }` ]
})
export class LoveComponent {
isSelected = true;
onToggle() {
this.isSelected = !this.isSelected;
}
}
NgStyle:
import { Component } from '@angular/core';
@Component({
selector: 'app-technologies',
template: `
<div class="row">
<div class="col-6">
<h2>{{ title }}</h2>
<button [ngStyle]="{
'backgroundColor': canSave ? 'red' : 'green',
'color': canSave ? 'white' : 'black',
'width': canSave ? '150px' : '100px',
'fontWeight': canSave ? 'bold' : 'normal'
}">Save Her
</button>
</div>
<div class="col">
<img class="w-100 p-3 rounded-circle" [src]="imageUrl" />
<app-my-love></app-my-love>
</div>
</div>
`
})
export class TechnologiesComponent {
title = 'List of Technologies';
imageUrl = './assets/polymer3.jpg';
canSave = true;
}
Safe Traversal Operator:
<span >{{ task.assignee?.name }}</span>
Custom Directive:
import { Directive, HostListener, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[appInputFormat]'
})
export class InputFormatDirective {
@Input() appInputFormat;
constructor(private el: ElementRef) { }
@HostListener('focus') onFocus() {
console.log('on focus');
}
@HostListener('blur') onBlur() {
const value: string = this.el.nativeElement.value;
this.el.nativeElement.value =
(this.appInputFormat === 'lowercase') ? value.toLowerCase() : value.toUpperCase();
}
}
Host Component:
import { Component } from '@angular/core';
@Component({
selector: 'app-technologies',
template: `
<div class="row">
<div class="col-6">
<h2>{{ title }}</h2>
<input type="text" [appInputFormat]="'uppercase'">
</div>
<div class="col">
<img class="w-100 p-3 rounded-circle" [src]="imageUrl" />
<app-my-love></app-my-love>
</div>
</div>
`
})
export class TechnologiesComponent {
title = 'List of Technologies';
imageUrl = './assets/polymer3.jpg';
}