Loading
Suguru Inatomi
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
@laco0416
2016/9/3 HTML5 Conference
http://shop.oreilly.com/product/9781939902375.do
@Component({
selector: "app-profile",
template: "<p>Name: {{ name }}</p>"
})
class ProfileComponent {
@Input() name: string;
}
<div>
<app-profile name="laco"></app-profile>
</div>
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;
}
Event Handling: (event)
@Component({
template: `
<button (click)="onClick($event)">
`
})
class MyComponent {
onClick(e: MouseEvent) {
}
}
@angular/core
@angular/forms
@angular/http
@angular/router
Testing
Angular Material
Angular Universal: Server side
AngularFire: Firebase
Types as API documents
Always correct
Compiler check
Auto-completions
Spec: javascript-decorators
Status: tc39/proposals
tsc --experimentalDecorators
Good-bye "$http"
import {Http} from "@angular/http";
@Injectable()
class MyService {
constructor(private anyNameForHttp: Http) {
}
}
@Component()
@Input() / @Output()
@Directive()
@Pipe()
@NgModule()
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!';
}
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;
}
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); }
}
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>
Data transformer
import {Pipe} from '@angular/core';
@Pipe({
name: 'quote'
})
class QuotePipe {
transform(value) {
return `"${value}"`;
}
}
<p>{{ message | quote }}</p>
Module
Components
Application
Platform
Directives
Pipes
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 {}
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);
2015 ng-conf: New Router
2015 AngularConnect: Component Router
2016 ng-conf Router v2
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: '/'}
];
import RouterModule
import {RouterModule} from '@angular/router';
import {appRoutes} from './app.routes';
@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
})
class MyAppModule {}
<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 {}
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}`);
});
}
}
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'];
Angular 2 💖 Web Standards
Angular 2 💖 TypeScript
Simple & Useful APIs
Platform/Module/Component Tree
Router v3: Easy