Angular components 2
May 2017, Nejc Zdovc
workshop #8
AGENDA
Projection
Encapsulation
Two-Way binding
Events, Host binding
pipes (usage)
ngSwitch
ngClass
ngStyle
Projection
Single-slot content
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<div class="my-component">
<ng-content></ng-content>
</div>
`
})
export class MyComponent {}
my-component.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<div class="app">
<my-component>
This is my transcluded content!
</my-component>
</div>
`
})
export class AppComponent {}
app.component.ts
MULTI-slot content
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<div class="my-component">
<div>
Title:
<ng-content
select=".my-component-title">
</ng-content>
</div>
<div>
Content:
<ng-content
select=".my-component-content">
</ng-content>
</div>
</div>
`
})
export class MyComponent {}
my-component.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<div class="app">
<my-component>
<div class="my-component-title">
This is the Component title!
</div>
<div class="my-component-content">
And here's some awesome content.
</div>
</my-component>
</div>
`
})
export class AppComponent {}
app.component.ts
Encapsulation
NONE
<!DOCTYPE html>
<html>
<head>
<style>
p {
color: red;
}
</style>
</head>
<body>
<my-component>
<p>This is title</p>
</my-component>
</body>
</html>
generated index.html
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
This is title
</p>
`,
styles: [`
p {
color: red;
}
`],
encapsulation: ViewEncapsulation.None
})
export class MyComponent {}
my-component.component.ts
Emulated - Default
<!DOCTYPE html>
<html>
<head>
<style>
p[_ngcontent-0] {
color: red;
}
</style>
</head>
<body>
<my-component _ngcontent-0>
<p _ngcontent-0>This is title</p>
</my-component>
</body>
</html>
generated index.html
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
This is title
</p>
`,
styles: [`
p {
color: red;
}
`],
encapsulation: ViewEncapsulation.Emulated
})
export class MyComponent {}
my-component.component.ts
NATIVE
<!DOCTYPE html>
<html>
<body>
<my-component>
#shadow-root
| <style>
| p {
| color: red;
| }
| </style>
| <p>This is title</p>
</my-component>
</body>
</html>
generated index.html
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
This is title
</p>
`,
styles: [`
p {
color: red;
}
`],
encapsulation: ViewEncapsulation.Native
})
export class MyComponent {}
my-component.component.ts
Two-Way binding
LONG VERSION
<input [ngModel]="username" (ngModelChange)="username = $event">
<p>Hello {{username}}!</p>
hello.component.html
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: 'hello.component.html'
})
export class HelloComponent {
username = 'Angular';
}
hello.component.ts
<input [value]="username" (input)="username = $event.target.value">
<p>Hello {{username}}!</p>
SHORT VERSION
<input [(ngModel)]="username">
<p>Hello {{username}}!</p>
hello.component.html
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
templateUrl: 'hello.component.html'
})
export class HelloComponent {
username = 'Angular';
}
hello.component.ts
Host binding /
HOST LISTENER
HOST LISTENER
import {Component, HostListener} from '@angular/core';
@Component({
selector: 'hello-component',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent {
@HostListener('mouseenter') onMouseEnter() {
console.log('mouse entered hello component');
}
@HostListener('mouseleave', ['$event']) onMouseLeave(e) {
console.log('mouse left component', e);
}
}
hello.component.ts
HOST BINDING
import {Component, HostBinding} from '@angular/core';
@Component({
selector: 'hello-component',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent {
@HostBinding('class.valid') isValid = false;
onClick() {
this.isValid = true;
}
}
hello.component.ts
<button (click)="onClick()">Validate</button>
hello.component.html
PIPES
UPPERCASE
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
{{ title | uppercase }}
</p>
`,
})
export class MyComponent {
title = 'This is title'
}
my-component.component.ts
THIS IS TITLE
output
LOWERCASE
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
{{ title | lowercase }}
</p>
`,
})
export class MyComponent {
title = 'This is title'
}
my-component.component.ts
this is title
output
DATE
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>
{{ birthday | date:"dd. MM. yyyy" }}
</p>
<p>
{{ birthday | date:"fullDate" | uppercase }}
</p>
`,
})
export class MyComponent {
birthday = new Date(1988, 3, 15); // April 15, 1988
}
my-component.component.ts
15. 04. 1988
FRIDAY, APRIL 15, 1988
output
NUMBER
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>e (no formatting): {{e}}</p>
<p>e (3.1-5): {{e | number:'3.1-5'}}</p>
<p>pi (no formatting): {{pi}}</p>
<p>pi (3.5-5): {{pi | number:'3.5-5'}}</p>
`,
})
export class MyComponent {
pi: number = 3.141592;
e: number = 2.718281828459045;
}
my-component.component.ts
e (no formatting): 2.718281828459045
e (3.1-5): 002.71828
pi (no formatting): 3.141592
pi (3.5-5): 003.14159
output
CURRENCY
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>A: {{a | currency:'USD':false}}</p>
<p>B: {{b | currency:'USD':true:'4.2-2'}}</p>
`,
})
export class MyComponent {
a: number = 0.259;
b: number = 1.3495;
}
my-component.component.ts
A: USD0.26
B: $0,001.35
output
PERCENT
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `
<p>A: {{a | percent}}</p>
<p>B: {{b | percent:'4.3-5'}}</p>
`,
})
export class MyComponent {
a: number = 0.259;
b: number = 1.3495;
}
my-component.component.ts
A: 25.9%
B: 0,134.950%
output
ng*
ngswitch
<div [ngSwitch]="carType">
<span *ngSwitchCase="family">Welcome family guy</span>
<span *ngSwitchCase="sport">Wruum Wruuum</span>
<span *ngSwitchCase="off-roaders">Hi you on the hill</span>
<span *ngSwitchCase="luxury">Blink Blink</span>
<p *ngSwitchDefault>Motorcycle is fine as well</p>
</div>
hello.component.html
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent implements OnInit {
carType: string = 'family' | 'sport' | 'off-roaders' | 'luxury';
ngOnInit() {
this.carType = 'sport';
}
}
hello.component.ts
NGCLASS
<div [ngClass]="{'first': isFirst, 'second': !isFirst, 'third': true}">
Who is it?
</div>
<button (click)="onClick()">Toggle first</button>
hello.component.html
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent implements OnInit {
isFirst: boolean = true;
onClick() {
this.isFirst = !this.isFirst;
}
}
hello.component.ts
NGSTYLE
<div [ngStyle]="{
'color': getRandomColor(),
'font-size: '16px'
}">
RAINBOW
</div>
hello.component.html
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'hello',
templateUrl: './hello.component.html',
styleUrls: ['./hello.component.css']
})
export class HelloComponent implements OnInit {
getRandomColor(){
const chars: string[] = '0123456789ABCDEF'.split('');
let color = '#';
for (let i = 0; i < 6; i++){
color += chars[Math.floor(Math.random() * 16)];
}
return color;
}
}
hello.component.ts
THANK YOU

Workshop #8 - Components 2
By Angular Slovenia
Workshop #8 - Components 2
- 756