The First Step to Angular

@laco2net
2017-09-24 HTML5 Conference
about me

- 稲富 駿 (laco)
- Kaizen Platform
- ng-japan Organizer
- Angular Contributor
Why is Angular popular?
Angular Overview
Angular
- Web Standards
- Simple
- Easy
- Fast
- Full-stack
- Powered by


Angular Web Standards
- ECMAScript 2015+
- ES Modules
- Web Animations API
- Web Components
-
ES Proposal
- Decorators
- 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) {
}
}
Angular CLI
# Install Angular CLI
> npm install -g @angular/cli
# Create new app
> ng new hello-angular
# Test
> ng test
# Build
> ng build --prod
# Debug
> ng serve
Easy to develop Angular apps
High Performance
- Smart Change Detector
- Code Generation
- 100k checks / 10ms
- Reduce detection
- Triggered by Zone.js
- Code Generation
- Smart Renderer
- Reduce DOM manipulations

Official Packages
-
@angular/core
-
@angular/common
-
@angular/forms
-
@angular/http
-
@angular/router
-
@angular/material
-
@angular/platform-server
-
@angular/service-worker
-
@angular/language-service
-
...
TypeScript
-
Static Type
-
Decorators
-
Type-base Dependency Injection
-
Language Services

Static Types
-
Benefit of Type
-
Code as Living API doc
-
Always correct
-
-
-
Compiler check
-
Compilation is the easiest test
-
-
Auto-completions
-
Language Services Helps your editor
-

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

Language Service
Types in the template


Angular Basic APIs
Basic APIs
-
@Component()
-
@Input() / @Output()
-
@Directive()
-
@Pipe()
-
@NgModule()
@Component
It's a component because it composes app
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
`,
styles: [`h1 { color: blue; }`]
})
export class MyAppComponent {
title = 'Hello World!';
}
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: '[underline]'
})
class BootstrapBtn {
@HostBinding('style') hostStyle = "text-decoration: underline";
}
<span underline>Text</span>
<span style="text-decoration: underline">Text</span>
@Pipe
Data transformer
import {Pipe} from '@angular/core';
@Pipe({
name: 'quote'
})
class QuotePipe {
transform(value) {
return `"${value}"`;
}
}
<p>{{ message | quote }}</p>
Angular Architecture
Module
Components
Application
Platform
Directives
Pipes
Module
Module
Module
Services
Angular Modules
Application Configuration
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
import {
platformBrowser
} from '@angular/platform-browser';
import {
platformBrowserDynamic
} from '@angular/platform-browser-dynamic';
import {
platformServer
} from '@angular/platform-server';
import {MyAppModule} from './app.module';
platformBrowserDynamic().bootstrapModule(MyAppModule);
Angular Ecosystem
Angular is a Platform


What is Angular's job?

Responsibility
-
Render View
-
Watch model's change
-
Transit View
-
Access to Server
Render Views
Data Model
View
Rendering
Data Model
View
@Component({
template: "<h1>{{title}}</h1>"
})
class MyComponent {
title = "Hello!";
}
<h1>Hello!</h1>
Watch model's change
Change Detection


Routing
Transit View


Angular Router
-
URL-Component Mapping
-
Guard & Resolve
-
Nesting
-
Lazy-Loading
Access to Server
AJAX
@Injectable()
export class HeroService {
constructor (private http: HttpClient) {}
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>("/api/heroes");
}
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>("/api/heroes", hero);
}
}
Http Service
Angular Http
-
Wrap XHR/JSONP
-
Return Observable<T>
-
Lazy-Execution
-
Aborting
-
Multi-Responses
-
-
Interceptor
-
Progress Event
@Injectable()
export class MyInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
newReq = req.clone({
headers: new HttpHeaders({ 'X-AUTHOR': 'laco' })
});
return next.handle(newReq);
}
}
Http Interceptor
http.post('/upload/file', file, { reportProgress: true })
.subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
const percentDone =
Math.round(100 * event.loaded / event.total);
console.log(`File is ${percentDone}% uploaded.`);
} else if (event instanceof HttpResponse) {
console.log('File is completely uploaded!');
}
});
Http Progress
Additional Features
-
Animations
-
Server-side Rendering
-
UI Components
-
Debugger
-
Editor Plugins
-
Developer Tool
Angular Animations
@Component({
animations: [
trigger("visibility", [
state("shown", style({ opacity: 1 })),
state("hidden", style({ opacity: 0 })),
transition("* => *", animate(".5s"))
])
],
template: `
<div [@visibility]="visibility">
`
})
class MyComponent() {
visibility = 'hidden';
}
Server-side Rendering
import { renderModule } from '@angular/platform-server';
renderModule(AppServerModule, {
document: fs.readFileSync('src/index.html', 'utf8'),
url: '/'
}).then(html => {
fs.writeFileSync('dist/index.html', html);
});
@angular/platform-server
Angular Material

Angular CLI
-
Scaffold Angular project
-
Tasks
-
Generate code
-
Debug
-
Test
-
Lint
-
-
Full of Best Practices

Angular Language Service
-
VSCode Plugin (Official)
-
WebStorm (Built-in)

@angular/language-service
Augury
-
Chrome Extension for Angular Debugging

Missing Piece?
Documentation
angular.io

angular.io as a doc
- Tutorial
- Fundamentals
- Techniques
- API References
- Generated from source
- Always correct

angular.io as an app
-
Built on Latest Angular
-
Progressive Web App
-
Offline
-
Add to Homescreen
-
-
Source Code
-
angular/angular: /aio
-
How to learn Angular?
Learn Angular
-
Read angular.io
-
Official documentation
-
-
Use Angular CLI
-
Follow the Best Practice
-
- ES2015+
- ES Modules
- TypeScript
- RxJS / Observables
- (webpack)
- (Component Design)
Required Knowledges
Modern Web => Angular, React, Vue, ...
"The Web has moved.
Frameworks must move"
Understand the Web
Semantic Versioning
Angular x.y.z
-
x: major
-
Update can contain breaking changes
-
-
y: minor
-
Update cannot breaking changes
-
-
z: patch
-
Only bug fix
-
Time-base Release
-
Every weak: patch update
-
Every month: minor update
-
Every 6 months: major update

Keep an eye
on changes


Watch CHANGELOG
Read Release Note

Read Release Note

Join communities

Conclusion
-
Angular is a Platform for Developer Experience
-
Basic APIs are Simple & Useful
-
How to learn Angular
-
Read angular.io
-
Use Angular CLI
-
Follow the Best Practice
-
Understand the Web
-
Keep an eye on changes
-
Thanks!

The First Step to Angular
By Suguru Inatomi
The First Step to Angular
HTML5 Conference 2017
- 5,443