Angular Essentials 2
Lifecycle Hooks
Lifecycle Hooks
ngOnChanges()
import { Component, OnChanges, SimpleChanges } from '@angular/core';
@Component({
...
})
export class AComponent implements OnChanges {
// only called for/if there is an @input variable set by parent.
ngOnChanges(changes: SimpleChanges) {
...
}
}
ngOnInit()
import { Component, OnInit } from '@angular/core';
@Component({
...
})
export class AComponent implements OnInit {
// implement OnInit's `ngOnInit` method
ngOnInit() {
...
}
}
ngDoCheck()
import { Component, DoCheck } from '@angular/core';
@Component({
...
})
export class AComponent implements DoCheck {
// Beware! Called frequently!
// Called in every change detection cycle anywhere on the page
ngDoCheck() {
...
}
}
ngAfterContentInit()
import { Component, AfterContentInit } from '@angular/core';
@Component({
...
})
export class AComponent implements AfterContentInit {
ngAfterContentInit() {
...
}
}
ngAfterContentChecked()
import { Component, AfterContentChecked } from '@angular/core';
@Component({
...
})
export class AComponent implements AfterContentChecked {
// Beware! Called frequently!
// Called in every change detection cycle anywhere on the page
ngAfterContentChecked() {
...
}
}
ngAfterViewInit()
import { Component, AfterViewInit } from '@angular/core';
@Component({
...
})
export class AComponent implements AfterViewInit {
ngAfterViewInit() {
...
}
}
ngAfterViewChecked()
import { Component, AfterViewChecked } from '@angular/core';
@Component({
...
})
export class AComponent implements AfterViewChecked {
// Beware! Called frequently!
// Called in every change detection cycle anywhere on the page
ngAfterViewChecked() {
...
}
}
ngOnDestroy()
import { Component, OnDestroy } from '@angular/core';
@Component({
...
})
export class AComponent implements OnDestroy {
ngOnDestroy() {
...
}
}
Structural directive
The asterisk (*) prefix
# Sugared directive
<div *ngIf="hero" >{{hero.name}}</div>
# Desugar step 1
<div template="ngIf hero">{{hero.name}}</div>
# Desugar step 2
<ng-template [ngIf]="hero">
<div>{{hero.name}}</div>
</ng-template>
ngIf
<p *ngIf="true">
Expression is true and ngIf is true.
This paragraph is in the DOM.
</p>
<p *ngIf="false">
Expression is false and ngIf is false.
This paragraph is not in the DOM.
</p>
ngFor
<div *ngFor="let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
({{i}}) {{hero.name}}
</div>
ngFor
<div *ngFor="
let hero of heroes;
let i=index;
let odd=odd;
trackBy: trackById"
[class.odd]="odd">
({{i}}) {{hero.name}}
</div>
<div template="
ngFor let hero of heroes;
let i=index;
let odd=odd;
trackBy: trackById"
[class.odd]="odd">
({{i}}) {{hero.name}}
</div>
<ng-template
ngFor
let-hero
[ngForOf]="heroes"
let-i="index"
let-odd="odd"
[ngForTrackBy]="trackById">
<div [class.odd]="odd">({{i}}) {{hero.name}}</div>
</ng-template>
ngSwitch
<div [ngSwitch]="hero?.emotion">
<happy-hero *ngSwitchCase="'happy'" [hero]="hero"></happy-hero>
<sad-hero *ngSwitchCase="'sad'" [hero]="hero"></sad-hero>
<confused-hero *ngSwitchCase="'confused'" [hero]="hero"></confused-hero>
<unknown-hero *ngSwitchDefault [hero]="hero"></unknown-hero>
</div>
ngSwitch
<div [ngSwitch]="hero?.emotion">
<happy-hero template="ngSwitchCase 'happy'" [hero]="hero"></happy-hero>
<sad-hero template="ngSwitchCase 'sad'" [hero]="hero"></sad-hero>
<confused-hero template="ngSwitchCase 'confused'" [hero]="hero"></confused-hero>
<unknown-hero template="ngSwitchDefault" [hero]="hero"></unknown-hero>
</div>
<div [ngSwitch]="hero?.emotion">
<ng-template [ngSwitchCase]="'happy'">
<happy-hero [hero]="hero"></happy-hero>
</ng-template>
<ng-template [ngSwitchCase]="'sad'">
<sad-hero [hero]="hero"></sad-hero>
</ng-template>
<ng-template [ngSwitchCase]="'confused'">
<confused-hero [hero]="hero"></confused-hero>
</ng-template >
<ng-template ngSwitchDefault>
<unknown-hero [hero]="hero"></unknown-hero>
</ng-template>
</div>
Group sibling elements
<select [(ngModel)]="hero">
<ng-container *ngFor="let h of heroes">
<ng-container *ngIf="showSad || h.emotion !== 'sad'">
<option [ngValue]="h">{{h.name}} ({{h.emotion}})</option>
</ng-container>
</ng-container>
</select>
NO <span>
Attribute directives
<p myHighlight>Highlight me!</p>
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
Attribute directives
<p [myHighlight]="color">Highlight me!</p>
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[myHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) { }
@Input('myHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter() {
this.highlight(this.highlightColor || 'red');
}
@HostListener('mouseleave') onMouseLeave() {
this.highlight(null);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
Built in Attribute directives
<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
This div is x-large or smaller.
</div>
NgClass
currentClasses: {};
setCurrentClasses() {
// CSS classes: added/removed per current state of component properties
this.currentClasses = {
saveable: this.canSave,
modified: !this.isUnchanged,
special: this.isSpecial
};
}
<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>
NgStyle
currentStyles: {};
setCurrentStyles() {
// CSS styles: set per current state of component properties
this.currentStyles = {
'font-style': this.canSave ? 'italic' : 'normal',
'font-weight': !this.isUnchanged ? 'bold' : 'normal',
'font-size': this.isSpecial ? '24px' : '12px'
};
}
<div [ngStyle]="currentStyles">
This div is initially italic, normal weight, and extra large (24px).
</div>
NgModel
<input [(ngModel)]="currentHero.name">
<input [value]="currentHero.name"
(input)="currentHero.name=$event.target.value" >
NgModel
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular
/* Other imports */
@NgModule({
imports: [
BrowserModule,
FormsModule // <--- import into the NgModule
],
/* Other module metadata */
})
export class AppModule { }
Custom Attribute directives
<p myFavorite>Text!</p>
import { Directive, HostBinding } from '@angular/core';
@Directive({
selector: '[myFavorite]'
})
export class FavoriteDirective {
@HostBinding('class.is-favorite') isFavorite = true;
}
Using directive values
<p [myFavorite]="item.favorite">Text!</p>
import { Directive, HostBinding, Input } from '@angular/core';
@Directive({
selector: '[myFavorite]'
})
export class FavoriteDirective {
@HostBinding('class.is-favorite') isFavorite = true;
@Input() set myFavorite(value) {
this.isFavorite = value;
}
}
Working with events in directives
<p [myFavorite]="item.favorite">Text!</p>
import { Directive, HostBinding, Input, HostListener } from '@angular/core';
@Directive({
selector: '[myFavorite]'
})
export class FavoriteDirective {
@HostBinding('class.is-favorite') isFavorite = true;
@HostBinding('class.is-favorite-hovering') hover = false;
@HostListener('mouseenter') onMouseEnter {
this.hover = true;
}
@HostListener('mouseleave') onMouseLeave {
this.hover = false;
}
@Input() set myFavorite(value) {
this.isFavorite = value;
}
}
Pipes built in
<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
The chained hero's birthday is
{{ birthday | date:'fullDate' | uppercase}}
Pipes built in
Pipes custom
import { Pipe, PipeTransform } from '@angular/core';
/*
* Raise the value exponentially
* Takes an exponent argument that defaults to 1.
* Usage:
* value | exponentialStrength:exponent
* Example:
* {{ 2 | exponentialStrength:10}}
* formats to: 1024
*/
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
transform(value: number, exponent: string): number {
let exp = parseFloat(exponent);
return Math.pow(value, isNaN(exp) ? 1 : exp);
}
}
angular-essentials-2
By Shuhratbek Mamadaliyev
angular-essentials-2
- 1,141