@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