The First Step to
Angular 2

@laco0416
2016/9/3 HTML5 Conference
about me

- TOPGATE, Inc.
- Angular 2 Contributor
- Angular2 Info
ng2-info.github.io


Developing an Angular 2 Edge
http://shop.oreilly.com/product/9781939902375.do

Agenda
- Angular 2 Overview
- Final APIs
- Angular 2 Router
Angular 2
- Web Standards
- Simple
- Fast
- Full-stack
- Powered by


Web Standards Friendly
- ECMAScript 2015
- Web Worker
- Decorators
- Web Animations API
- Web Components
- Fetch API
- Observables
- Zones
Component definition
@Component({
selector: "app-profile",
template: "<p>Name: {{ name }}</p>"
})
class ProfileComponent {
@Input() name: string;
}
<div>
<app-profile name="laco"></app-profile>
</div>

Template Syntax (1)
Data-Binding: [prop]
@Component({
template: `
<input [value]="name">
<div [attr.role]="role"></div>
<div [class.large]="isLarge"></div>
<div [style.width.px]="mySize"></div>
`
})
class MyComponent {
name = "laco";
role = "main"
isLarge = true;
mySize = 16;
}
Template Syntax (2)
Event Handling: (event)
@Component({
template: `
<button (click)="onClick($event)">
`
})
class MyComponent {
onClick(e: MouseEvent) {
}
}
High Performance
- Smart Change Detector
- One-way Checking
- 100000 checks / 10ms


Official Packages
-
@angular/core
-
@angular/forms
-
@angular/http
-
@angular/router
-
Testing
-
Angular Material
-
Angular Universal: Server side
-
AngularFire: Firebase
TypeScript
- Static Type
- Decorators
- Type-base Dependency Injection

Static Types
Types as API documents
-
Always correct
-
Compiler check
-
Auto-completions

@Decorators()
Next generation standardSpec: javascript-decorators
Status: tc39/proposals
- Class and Property: Stage 2
- Function: Stage 0
- Method: Stage 0
tsc --experimentalDecorators
Type-base DI
IOW, "Typo-safe" DIGood-bye "$http"
import {Http} from "@angular/http";
@Injectable()
class MyService {
constructor(private anyNameForHttp: Http) {
}
}

Angular 2 Final APIs
Basic APIs
-
@Component()
-
@Input() / @Output()
-
@Directive()
-
@Pipe()
-
@NgModule()
@Component
It's a component because it composes app
-
Component = Directive + Template
-
CSS Encapsulation
-
Build Component Tree
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
`,
styles: [`h1 { color: blue; }`]
})
export class MyAppComponent {
title = 'Hello World!';
}
Demo
Component Tree
Top-down Data Flow: @Input()
@Component({
selector: 'my-app',
template: `<profile [name]="myName"></profile>`
})
class MyAppComponent {
myName = 'laco';
}
@Component({
selector: 'profile',
template: `<p>{{name}}</p>`
})
class ProfileComponent {
@Input() name;
}
Component Tree
Bottom-up Event System: @Output()
@Component({
selector: 'my-app',
template: `<app-menu (select)="onMenuSelect($event)"></app-menu>`
})
class MyAppComponent {
onMenuSelect(menuItem) { }
}
@Component({
selector: 'app-menu',
template: `...`
})
class MenuComponent {
@Output() select = new EventEmitter();
selectMenu(menuItem) { this.select.emit(menuItem); }
}
@Directive
Extend elements
import {Directive, HostBinding} from '@angular/core';
@Directive({
selector: '[bsBtnPrimary]'
})
class BootstrapBtn {
@HostBinding('class') classNames = "btn btn-primary";
}
<button bsBtnPrimary>Primary Button</button>
<button class="btn btn-primary">Primary Button</button>
@Pipe
Data transformer
import {Pipe} from '@angular/core';
@Pipe({
name: 'quote'
})
class QuotePipe {
transform(value) {
return `"${value}"`;
}
}
<p>{{ message | quote }}</p>
Angular 2 Architecture
Module
Components
Application
Platform
Directives
Pipes
Angular Modules
Application Configuration
-
Import other modules
-
Create Compiler
-
Setup Injector
-
bootstrapping
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {MyAppComponent} from './app.component';
import {MyOtherComponent} from './other.component';
import {MyService} from './my.service';
@NgModule({
imports: [BrowserModule],
declarations: [MyOtherComponent, MyAppComponent],
providers: [MyService],
bootstrap: [MyAppComponent]
})
export class MyAppModule {}
Angular Platforms
Application Environment
-
Browser (JIT, AoT)
-
Web Worker
-
Server
import {
platformBrowser
} from '@angular/platform-browser';
import {
platformBrowserDynamic
} from '@angular/platform-browser-dynamic';
import {
platformWorkerApp, platformWorkerUi
} from '@angular/platform-webworker';
import {
platformServer, platformServerDynamic
} from '@angular/platform-server';
import {MyAppModule} from './app.module';
platformBrowserDynamic().bootstrapModule(MyAppModule);
Angular 2 Router
a long time ago...



2015 ng-conf: New Router
2015 AngularConnect: Component Router
2016 ng-conf Router v2





Router v3

Route Configuration
path-component patterns
export const appRoutes = [
// .../
{ path: '', pathMatch: 'full', component: HomeCmp },
// .../about
{ path: 'about', component: AboutCmp },
{
// nested routes
path: 'users', children: [
// .../users
{ path: '', pathMatch: 'full', component: UserListCmp },
// .../users/11
{ path: ':id', component: UserDetailCmp }
]
},
// wildcard route
{ path: '**', redirectTo: '/'}
];
Install Router
import RouterModule
import {RouterModule} from '@angular/router';
import {appRoutes} from './app.routes';
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
})
class MyAppModule {}
Use Router
<router-outlet> & routerLink
@Component({
template: `
<nav>
<a routerLink="/">Home</a> |
<a routerLink="/about">About</a>
</nav>
<main>
<router-outlet></router-outlet>
</main>
`
})
export class MyAppComponent {}
Router v3 Architecture

Router State
ActivatedRoute 💖 Observable
@Component({
template: `
<nav>...</nav>
<main>
<router-outlet></router-outlet>
</main>
`
})
export class MyAppComponent {
constructor(private route: ActivatedRoute) {
route.url.subscribe(url => {
console.log(`URL changed: ${url}`);
});
}
}
Router State
Async / Sync
// URL Changes
route.url.subscribe(...);
// Params (/users/:id)
route.params.subscribe(...);
// QueryParams (?foo=bar)
route.queryParams.subscribe(...);
// Fragment (#section1)
route.fragment.subscribe(...);
// Sync Snapshot
route.snapshot.params['id'];
Demo
Conclusion
-
Angular 2 💖 Web Standards
-
Angular 2 💖 TypeScript
-
Simple & Useful APIs
-
Platform/Module/Component Tree
-
Router v3: Easy
Thanks!

The First Step to Angular 2
By Suguru Inatomi
The First Step to Angular 2
- 7,371