Angular 2 Essential Training

Preview:

Citation preview

Patrick Schroeder

Typescript

Components

NgModules

Data Binding

Directives

Pipes

Inputs / Outputs

Observables

Routing

and more…

What you’ll Learn

ES5

Dart

CoffeeScript

ES2015 or ES7

Typescript

So Many Options!

SPA (single-page app)

o index.htmlDynamic, Rich, & Fast

Browser-Loaded

Cleaner Code

o if conditions, loops, vars

o data-binding {{ bindMe }}

What is Angular?

Loading Content

Server

Application

Server

+

SQL

Dataset

Template

Browser

Final HTML page

Browser

Application

Server

+

SQL

Dataset

Template

Browser

Final HTML page

Guiding Principles

Fast Friendly Modern

Angular 2 Features

Fast

Angular 2 Features

Initial Loads

Change Detection

Rendering

Friendly

Angular 2 Features

Simplified API

Better Patterns

Modern

Angular 2 Features

Components

Responsive

ES2015

Javascript Advances

Classes

Modules

Decorators

Typescript

ES2015

ES7

Strong Typing

Typescript Features

White

ECMAScript 5

ECMAScript 2015

TypeScript

Typescript = All the JavaScript

Creates Strong Typing

var myVar: string = “Happy”;

Strings, Booleans, Arrays

Type Annotations

Function Function ParameterProperty

export class AppComponent {

pageTitle: string = “Welcome";

}

function isFalse: boolean {

return false;

}

function sayHello(input: string): string{

return “Hello " + input;

}

Type Examples

Function void

function isFalse: void {

console.log(‘my message’);

}

Syntax Checking = Fewer Bugs

IDE Supporto code completion, highlighting, error checking

Strong Typing Benefits

Enhanced JavaScript

Strong Typing

IDE Support

TypeScript Benefits

Angular 2 Setup

Developer Environment• editors and plugins

Get going!• angular.io Quickstart

Setup Revisited• file explanation

Setup

Install Node.js

Text Editor

Install Plugins

Developer Environment

Create Container

Closed System

Import / Export

Modules

NgModules

@NgModule

Load Components

Bootstrapping

NgModule

NgModule

“Used in order to help us organize our application into cohesive blocks of functionality”

NgModule

app.module.ts

import { NgModule } from ‘@angular/core’;

import { BrowserModule } from

‘@angular/platform-browser’;

import { AppComponent } from ‘./app.component’;

@NgModule({

imports: [ BrowserModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ]

})

export class AppModule { } Class

Metadata

Import

NgModule

app.module.ts

import { NgModule } from ‘@angular/core’;

import { BrowserModule } from

‘@angular/platform-browser’;

import { AppComponent } from ‘./app.component’;

@NgModule({

imports: [ BrowserModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ]

})

export class AppModule { }

@NgModule()

@NgModule({

// compose Metadata

})

Bootstrapping

Bootstrapping

main.ts

import { platformBrowserDynamic } from

‘@angular/platform-browser-dynamic’;

import { AppModule } from ‘./app.module’;

const platform = platformBrowserDynamic();

platform.bootstrapModule(AppModule); bootstrap

const

Import

Root Component

app.component.ts

import { Component } from ‘@angular/core’;

@Component({

selector: ‘my-app’,

template: `<h1>My First Angular App</h1>`

})

export class AppComponent {}

Why Components?

Composition

Decorators & Classes

Directives

Styles & Templates

Components

Bootstrapper

main.ts

App Component

Sidebar Component

Posts Component

NavComponent

Component Structure

Widgets Component

Calendar Component

Building Components

Building Components

Component

Template Class Metadata

• View Layout

• HTML Code

• Supports View

• Contains Properties

and Methods

• Used inside @Decorator

• Extra instructions for

Angular

Component

app.component.ts

import { Component } from ‘@angular/core’;

@Component({

selector: ‘bs-app’,

template: `

<h1>{{ pageTitle }}</h1>

<div>App Component Test</div>`

})

export class AppComponent {

pageTitle: string = “Dev Book Store”;

showBook(): void {

// method logic here

}

}

Class

Metadata

Import

Component

app.component.ts

import { Component } from ‘@angular/core’;

@Component({

selector: ‘bs-app’,

template: `

<h1>{{ pageTitle }}</h1>

<div>App Component Test</div>`

})

export class AppComponent {

pageTitle: string = “Dev Book Store”;

showBook(): void {

// method logic here

}

}

@Component()

@Component({

// compose Metadata

})

Data Binding

Template

Methods

Properties

Class

{{pageTitle}}

1-way Binding• {{pageTitle}}

2-way Binding• [(ngModel)]=“searchFilter”

Event Binding• (click)=“hideImage()”

Types of Data Binding

1-way Binding

Interpolation

Template

export class AppComponent {

pageTitle: string =

“Dev Book Store”;

}

Class

<h1>{{ pageTitle }}</h1>

Property Binding

Template

<img [src]=“bookImageUrl”>

Element

Property

Class

Property

export class BookListComponent {

bookImageUrl: string = “app/images/656.jpg”

}

Class

1-way Binding

2-way Binding

Template

export class AppComponent {

searchBox: string = “”;

}

Class

<input [(ngModel)]=“searchBox”>

[()]

Banana in a Box

2-way Binding

import { FormsModule } from ‘@angular/forms’;

@NgModule({

imports: [

BrowserModule,

FormsModule

]

})

export class AppModule { }

AppModule

NgModule

app.module.ts

import { NgModule } from ‘@angular/core’;

import { BrowserModule } from

‘@angular/platform-browser’;

import { AppComponent } from ‘./app.component’;

@NgModule({

imports: [ BrowserModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ]

})

export class AppModule { } Class

Metadata

Import

Event Binding

“Used to respond to user actions like button clicks.”

Respond to User Actions• Button clicks

Event Binding

Template

(click)=“hideImage()” export class AppComponent {

hideImage(): void {

this.showImage = !this.showImage;

}

}

Class

Event Binding

https://developer.mozilla.org/en-US/docs/Web/Events

Directives

Directives

“An HTML element or attributethat is used to enhance and extend our HTML”

Component• <bs-app></bs-app>

Structural• NgIf, NgFor, NgStyle

Attribute• <p highlight></p>

Types of Directives

Types of Directives

Custom Structuralwelcome.component.ts

@Component({

selector: ‘bs-welcome’

})

app.component.ts

@Component({

selector: ‘bs-app’,

template: <bs-welcome></bs-welcome>

})

*ngIf=“showImage”

*ngFor=“let book of books”

Add, Remove or Update view elements

<tr *ngFor=“let book of books”>

<td>{{ book.title }}</td>

<td>{{ book.author }}</td>

<td>{{ book.price }}</td>

</tr>

Structural Directives

NgIf

books-list.component.html

<img *ngIf=“showImage”>

Add, Remove or Update view elements

- with Booleans

- with Conditionals

NgFor

- Instantiates a templateonce per item from an iterable.

- Can be array or object.- Repeats over list creating new templates.

NgFor

*ngFor=“let book of books”

<tr *ngFor=“let book of books”>

<td>{{ book.title }}</td>

<td>{{ book.author }}</td>

</tr>

books: any[] = [

{ title: “Moby Dick”, author: “Herman Melville”},

{ title: “War and Peace”, author: “Leo Tolstoy”},

{ title: “Ulysses”, author: “James Joyce”}

]

NgClass

books-list.component.html

<div [ngClass]=“{‘redClass’: showImage, ‘yellowClass’: !showImage}”>

Adds and removes CSS classes on an

HTML element

- used with Object to form Expressions

- with Arrays or Strings [ngClass]=“redClass”

Pipes

Pipes

“Allow us to transform or format our data”

Built-In = | uppercase

Custom = | myPipeName

Pipes

Using Pipes

Template

export class BooksListComponent {

books: any[] = [{

inStock: ‘yes’

}]

}

books-list.component.ts

<h1>{{ books.inStock | uppercase }}</h1>

YES

Built-In Pipes

Uppercase

Lowercase

Decimal

Currency

Date

Json

Built-in Pipes

1. Create File

2. Import into AppModule

3. Use in Template

Custom Pipes

Custom Pipes

Template

import { PipeTransform, Pipe } from '@angular/core';

@Pipe({

name: ‘limitChar'

})

export class TruncatePipe implements PipeTransform {

transform(input: string, args: string[]) {

// Perform transformation here

return…

}

}

truncate.pipe.ts

<h1>{{ books.results | limitChar }}</h1>

import { NgModule } from ‘@angular/core’;

import { AppComponent } from ‘./app.component’;

import { TruncatePipe } from ‘./truncate.pipe.ts’;

@NgModule({

declarations: [ AppComponent

TruncatePipe ],

bootstrap: [ AppComponent ]

})

app.module.ts

Interface

Interface

“Used in Typescript to define data types for properties and methods”

1. Definition

2. Examples

3. Use in App

Interface

Interface

export interface IBook {

id: string;

name: string;

releaseDate: Date;

description: string;

author: string;

price: number;

imageUrl: string;

damaged(reason: string): void;

}Method

Properties

Export

export interface IBook {

id: string;

name: string;

releaseDate: Date;

description: string;

author: string;

price: number;

imageUrl: string;

damaged(reason: string): void;

}

Interface

Strong Typing

Better Tooling

Development Time

Why Interfaces?

Lifecycle Hooks

1. Definition

2. Most Used Hooks

3. Examples

Lifecycle Hooks

Lifecycle Hooks

ComponentChild

Components

Removes & Watches

OnInit• Perform component initialization

OnChanges• Perform action when values change

OnDestroy• Perform clean-up

Lifecycle Hooks

Using Lifecycle Hooks

import { Component, OnInit } from '@angular/core';

@Component({

selector: ‘bs-books-list'

})

export class BooksListComponent implements OnInit {

ngOnInit() : void {

console.log(‘Inside OnInit’);

}

}

books-list.component.ts

Inputs and Outputs

1.Nested Components

2.@Input / @Output

3.Custom Events

Inputs and Outputs

Nested Components

Bootstrapper

main.ts

App Component

Sidebar Component

Posts Component

NavComponent

Sample Component Hierarchy

Widgets Component

Calendar Component

Child

Components

Send

Receive

@Input

“Allows data to flow from parent component to child component”

Inputs

Container Component

Nested Component

@Input() reviews: number; Input

child_component.ts

export class ParentComponent {

books: any[] = [{

bookReviews: 15

}]

}

Input

parent_component.ts

import { Component, Input } from '@angular/core';

@Component({

selector: ‘child'

})

export class ChildComponent {

Input() reviews: number;

}

parent_component.html

<div><h1>Parent Title</h1>

<p>body text…</p>

<child [reviews]=“book.bookReviews”>

</child>

</div>

child_component.html

<div>

<p>{{ reviews }}</p>

</div>

@Output

“Custom events that pass data from component to the outside world.”

Output

Container Component

Nested Component

@Output() notify: EventEmitter<string> = newEventEmitter<string>(); Output

EventEmitter

“Listens for something to happen and emits an event when triggered”

EventEmitter

notify

Child Component

Publishes to Parent

new EventEmitter

this.notify.emit(‘send message’)

Parent Component

Subscribes to

Output

(notify)=“actionMethod()”

child_component.ts

export class ParentComponent {

onNotifyClicked(message: string): void {

this.showMessage = message;

}

}

Output

parent_component.ts

import { Output, EventEmitter } from '@angular/core';

export class ChildComponent {

Output() notify: EventEmitter<string> =

new EventEmitter<string>();

onClick(): void {

this.notify.emit(‘Message from child’);

}

} parent_component.html

<div><h1>Parent Title</h1>

<p>{{ showMessage }}</p>

<child (notify)=“onNotifyClicked($event)”>

</child>

</div>

child_component.html

<div

(click)=“onClick()”>

<button>Click Me</button> </div>

Generic

“Defines the type of an instance. Such as a object or function. Example: MyObj<string>”

Services

What are Services• Building

• Registering

• Injecting

Dependency Injection• Singleton

Constructor• Initial setup

Services

Service

“Used to encapsulate logic that can be used across multiple components”

Data Service Component

Injector

Service

@NgModule({

imports: [ BrowserModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ],

providers: [ BookService ]

})

export class AppModule { }

book.service.ts

import { Injectable } from '@angular/core';

import { IBook } from ‘./models/book';

@Injectable()

export class BookService {

getBooks(): IBook[] {

// get all books

}

}

import { IBook } from ‘./models/book';

import { BookService } from ‘./book.service.ts';

export class BookComponent {

constructor(_bookService: BookService) { }

getAllBooks() {

this._bookService.getBooks()

}

}

app.module.ts book.component.ts

Constructor

import { IBook } from ‘./models/book';

import { BookService } from ‘./book.service.ts';

export class BookComponent {

constructor(private _bookService: BookService) { }

getAllBooks() {

this._bookService.getBooks()

}

}

book.component.ts

Special Method

Initial Setup

No Return Value

Constructor

HTTP & Observables

HTTP

Request

Response

- http

- Observable

Observables• compare to promises

Http Request• GET

• process as Observable

Subscribe• display data

HTTP & Observables

Observables

Observable

“An asynchronous stream of data we can subscribe to”

price 3

price 2

price 1

Observables

Single value

Not cancellable

Observable

Multiple values

Cancellable

Map, filter, reduce

Promisevs

HTTP

Using Http

import { HttpModule } from ‘@angular/http';

@NgModule({

imports: [ BrowserModule

HttpModule ],

declarations: [ AppComponent ],

bootstrap: [ AppComponent ],

providers: [ BookService ]

})

export class AppModule { }

book.service.ts

import { Injectable } from '@angular/core';

import { Http } from ‘@angular/http';

@Injectable()

export class BookService {

constructor(private _http: Http) { }

getBooks(): IBook[] {

return this._http

.get(‘api/books.json’)

.map((response: Response) => response.json())

}

}

app.module.ts

Routing

Simple Routing• <router-outlet>

routerLink• menu, buttons

Pass Parameters• book-details

Routing

1.<base href=“/”>

2.import RouterModule

3.Add path’s

4.<router-outlet>

Routing

Routing

import { RouterModule } from ‘@angular/router';

@NgModule({

imports: [ BrowserModule

RouterModule.forRoot([

{ path: “books”, component: BooksListComponent },

{ path: “”, redirectTo: “books”, pathMatch: “full” },

{ path: “**”, redirectTo: “books”, pathMatch: “full” }

]),

bootstrap: [ AppComponent ]

})

export class AppModule { }

index.html

<html>

<head>

<base href=“/”>

<router-outlet></router-outlet>

<!-- <bs-books-list></bs-books-list> -->

app.module.ts app.component.html

http://localhost:3000/books

RouterLink

<a [routerLink]=“[‘/books’]”>All Books</a>

{ path: ‘books’, component: BooksListComponent }

http://localhost:3000/books

1.new HomeComponent

2.set as default

3.add links to

‘home’ and ‘books’

Routing Challenge

Routing with Parameters

import { RouterModule } from ‘@angular/router';

@NgModule({

imports: [ BrowserModule

RouterModule.forRoot([

{ path: “books”, component: BooksListComponent },

{ path: “book/:id”, component: BookDetailsComponent },

{ path: “”, redirectTo: “books”, pathMatch: “full” },

{ path: “**”, redirectTo: “books”, pathMatch: “full” }

]),

bootstrap: [ AppComponent ]

})

export class AppModule { }

app.module.ts

Passing Route Parameters

books-list.component.html

{ path: “book/:id”, component: BookDetailsComponent }

app.module.ts

<h4>

<a [routerLink]=“[‘/book’, book.id]”>

{{ book.name }}

</a>

</h4>

Passing Route Parameters

books-list.component.html

{ path: “book/:id”, component: BookDetailsComponent }

app.module.ts

<h4>

<a [routerLink]=“[‘/book’, book.id]”>

{{ book.name }}

</a>

</h4>

Recommended