Upload
patrick-schroeder
View
1.063
Download
0
Embed Size (px)
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>