Share
Embed
An Introduction to Angular2
SQUER Solutions
April 30, 2016
Transcript
65 slides
-
Entstehung von JS • 10 Tage • Brendan Eich •
Standard durch ECMA • Laufzeitumgebung = Browser Mocha LiveScript -
Features Angular 2 • Speed & Performance • Simple &
Expressive • Cross Platorm • Routng • Dependency Injecton -
AngularJS 1 -> Angular2 • Ziele mit AngularJs 1 nicht
erreichbar Neues Framework • Binding • Dependency Injecton • Modularität • Performance -
Typescript • Open Source • Transpilieren zu JavaScript • Source
Maps • Typen • Module • Typ Inferenz • Klassen, Interfaces -
Setup Angular 2 • package.json • Angular 2 dependencies •
Dev dependencies • tsconfg.json • Confg fle für Typescript -
Sourcemap ist Bindeglied zwischen JavaScript und TypeScript Code sehr hilfreich
beim Debuggen tsconfg.json -
<html> <head> <title>Angular 2 QuickStart</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link
rel="stylesheet" href="styles/styles.css"> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script... /> <!-- 2. Configure SystemJS --> <script> System.config({ packages: { app: { format: 'register', defaultExtension: 'js' } } }); System.import('app/bootstrapper') .then(null, console.error.bind(console)); </script> </head> <body> <lw-app>Loading...</lw-app> </body> </html> Einstegspunkt für Angular Komponente index.html -
index.html <html> <head> <title>Angular 2 QuickStart</title> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/styles.css"> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script> <script... /> <!-- 2. Configure SystemJS --> <script> System.config({ packages: { app: { format: 'register', defaultExtension: 'js' } } }); System.import('app/bootstrapper') .then(null, console.error.bind(console)); </script> </head> <body> <lw-app>Loading...</lw-app> </body> </html> SystemJS Module Loader System.import('module to import') C#: using JAVA: import -
index.html import {bootstrap} from 'angular2/platform/browser'; import {Main} from './lw.componente'; bootstrap(Main);
<html> <head> <title>Angular 2 QuickStart</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="styles/styles.css"> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script> <script... /> <!-- 2. Configure SystemJS --> <script> System.config({ packages: { app: { format: 'register', defaultExtension: 'js' } } }); System.import('app/bootstrapper') .then(null, console.error.bind(console)); </script> </head> <body> <lw-app>Loading...</lw-app> </body> </html> bootstrapper.ts -
import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: ` <div
class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } Decorator Component component.ts -
Html-Tag component.ts import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template:
` <div class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } -
import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: ` <div
class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } component.ts -
import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: ` <div
class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } component.ts -
component.ts Binding import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template:
` <div class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } -
component.ts ngFor Binding •ngIf •ngSwitch •ngClass import {Component} from 'angular2/core';
@Component({ selector: 'lw-app', template: ` <div class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } -
component.ts ngFor Binding import {Component} from 'angular2/core'; @Component({ selector: 'lw-app',
template: ` <div class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersionen"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } -
component.ts Method Binding import {Component} from 'angular2/core'; @Component({ selector: 'lw-app',
template: ` <div class="linuxVersions"> <h1>{{title}}</h1> <input (click)="addYear()" type="button" value="add year to title"/> </div> ` }) export class Main { public title = "LinuxVersions"; public addYear(){ var currentYear = this.getCurrentYear(); this.title = "LinuxVersion in " + currentYear; } private getCurrentYear() : number { return (new Date()).getFullYear(); } } -
component.ts import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: `
<div class="linuxVersions"> <h1>{{title}}</h1> <input (click)="addYear()" type="button" value="add year to title"/> </div> ` }) export class Main { public title = "LinuxVersions"; public addYear(){ var currentYear = this.getCurrentYear(); this.title = "LinuxVersion in " + currentYear; } private getCurrentYear() : number { return (new Date()).getFullYear(); } } -
component.ts import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: `
<div class="linuxVersions"> <h1>{{title}}</h1> <div><input type="text" [(ngModel)]="title" ></div> <div><input (click)="addYear()" type="button" value="add year to title"/></div> </div> ` }) export class Main { public title = "LinuxVersionen"; public addYear(){ var currentYear = this.getCurrentYear(); this.title = "LinuxVersion in " + currentYear; } private getCurrentYear() : number { return (new Date()).getFullYear(); } } Two-Way Binding -
component.ts import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: `
<div class="linuxVersions"> <h1>{{title}}</h1> <div><input type="text" [(ngModel)]="title" ></div> <div><input (click)="addYear()" type="button" value="add year to title"/></div> </div> ` }) export class Main { public title = "LinuxVersionen"; public addYear(){ var currentYear = this.getCurrentYear(); this.title = "LinuxVersion in " + currentYear; } private getCurrentYear() : number { return (new Date()).getFullYear(); } } -
import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: ` <div
class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } component.ts -
import {Component} from 'angular2/core'; @Component({ selector: 'lw-app', template: ` <div
class="linuxVersions"> <h1>{{title}}</h1> <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> </div> ` }) export class Main { public title = "LinuxVersions"; public versions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] } component.ts Template: templateUrl: 'pathToTemplate.html' -
service.ts import {Injectable} from 'angular2/core' import {LinuxVersion} from "./linuxVersion"; @Injectable()
export class LinuxVersionService{ private linuxVersions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] getCurrentLinuxVersions() : Array<LinuxVersion>{ //this would probably call a webservice return this.linuxVersions; } addLinuxVersion(name: string, version: string) : void { this.linuxVersions.push({ name: name, number: version }); } } -
service.ts export interface LinuxVersion{ name: string; number: string; } import
{Injectable} from 'angular2/core' import {LinuxVersion} from "./linuxVersion"; @Injectable() export class LinuxVersionService{ private linuxVersions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] getCurrentLinuxVersions() : Array<LinuxVersion>{ //this would probably call a webservice return this.linuxVersions; } addLinuxVersion(name: string, version: string) : void { this.linuxVersions.push({ name: name, number: version }); } } -
service.ts import {Injectable} from 'angular2/core' import {LinuxVersion} from "./linuxVersion"; @Injectable()
export class LinuxVersionService{ private linuxVersions = [ { name: "Ubuntu", number: "1604"}, { name: "Linux Mint", number: "17.3"}, { name: "ElementaryOS", number: "0.3.2"}, { name: "Fedora", number: "23"} ] getCurrentLinuxVersions() : LinuxVersion[]{ //this would probably call a webservice return this.linuxVersions; } addLinuxVersion(name: string, version: string) : void { this.linuxVersions.push({ name: name, number: version }); } } = Singleton -
Component.ts import {Component} from 'angular2/core'; import {LinuxVersionService} from "./LinuxVersionService"; import
{LinuxVersion} from "./linuxVersion"; @Component({ selector: 'lw-app', template: ` <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> `, providers: [LinuxVersionService] }) export class Main { constructor(private _linuxVersionService: LinuxVersionService) { } get versions():Array<LinuxVersion> { return this._linuxVersionService.getCurrentLinuxVersions(); } } -
import {Component} from 'angular2/core'; import {LinuxVersionService} from "./LinuxVersionService"; import {LinuxVersion}
from "./linuxVersion"; @Component({ selector: 'lw-app', template: ` <ul *ngFor="#version of versions"> <li> <span class="version-name">{{version.name}}</span> <span class="version-number">{{version.number}}</span> </li> </ul> `, providers: [LinuxVersionService] }) export class Main { constructor(private _linuxVersionService: LinuxVersionService) { } get versions():Array<LinuxVersion> { return this._linuxVersionService.getCurrentLinuxVersions(); } } Component.ts versions : Array<LinuxVersion>; get version(): Array<LinuxVersion> { return ... } set version(): Array<LinuxVersion> { ... = value; } -
main.ts @Component({ selector: 'lw-app', template: ` <div class="linuxVersions"> <h1><a [routerLink]="['Versions']">{{title}}</a></h1>
<router-outlet></router-outlet> </div> `, directives: [ROUTER_DIRECTIVES], providers: [ROUTER_PROVIDERS] }) @RouteConfig([ { path: '/detail/:id', name: 'VersionDetail', component: VersionDetailComponent, }, { path: '/versions', name: 'Versions', component: VersionsComponent, useAsDefault: true } ]) export class Main { public title = "LinuxVersionen"; } -
main.ts @Component({ selector: 'lw-app', template: ` <div class="linuxVersions"> <h1><a [routerLink]="['Versions']">{{title}}</a></h1>
<router-outlet></router-outlet> </div> `, directives: [ROUTER_DIRECTIVES], providers: [ROUTER_PROVIDERS] }) @RouteConfig([ { path: '/detail/:id', name: 'VersionDetail', component: VersionDetailComponent, }, { path: '/versions', name: 'Versions', component: VersionsComponent, useAsDefault: true } ]) export class Main { public title = "LinuxVersionen"; } -
master.ts @Component({ selector: 'lw-versions', template: ` <ul *ngFor="#version of versions">
<li> <span class="version-number">{{version.number}}</span> <span class="version-name">{{version.name}}</span> <a (click)="getDetail(version)">get Details</a> </li> </ul> `, providers: [LinuxVersionService, ROUTER_PROVIDERS] }) export class VersionsComponent { constructor( private _router : Router, private _linuxVersionService: LinuxVersionService ) { } get versions():Array<LinuxVersion> { return this._linuxVersionService.getCurrentLinuxVersions(); } getDetail(version: LinuxVersion) { this._router.navigate(['VersionDetail', { id: version.id }]); } } -
detail.ts @Component({ selector: 'lw-version-detail', template: ` <div><b>Name</b> {{version.name}}</div> <div><b>Number</b> {{version.number}}</div>
<div><b>Id</b> {{version.id}}</div> `, providers: [LinuxVersionService] }) export class VersionDetailComponent implements OnInit{ version : LinuxVersion; constructor(private _linuxVersionService: LinuxVersionService, private _routeParams: RouteParams) { } ngOnInit() { let id = +this._routeParams.get('id'); this.version = this._linuxVersionService.getLinuxVersion(id) } } -
detail.ts @Component({ selector: 'lw-version-detail', template: ` <div><b>Name</b> {{version.name}}</div> <div><b>Number</b> {{version.number}}</div>
<div><b>Id</b> {{version.id}}</div> `, providers: [LinuxVersionService] }) export class VersionDetailComponent implements OnInit{ version : LinuxVersion; constructor(private _linuxVersionService: LinuxVersionService, private _routeParams: RouteParams) { } ngOnInit() { let id = this._routeParams.get('id'); this.version = this._linuxVersionService.getLinuxVersion(id) } } Lifecycle Hooks: •ngOnInit •ngOnChanges •ngOnDestroy •ngAferViewInit •ngDoCheck •… -
index.html detail.ts service.ts [DI] master.ts /Master / Detail[id] bootstrapper.ts main.ts
specs.ts Tests Test Runner -
service.spec.ts import { LinuxVersionService } from '../app/linuxVersionService'; import {describe, it,
beforeEach, expect} from 'angular2/testing'; describe('LinuxVersionService', () => { var linuxVersionService: LinuxVersionService = null; beforeEach(()=>{ linuxVersionService = new LinuxVersionService(); }); it('can add linuxVersion', () => { let expectedVersionCount = linuxVersionService.getCurrentLinuxVersions().length + 1; linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); let actualVersionCount = linuxVersionService.getCurrentLinuxVersions().length; expect(actualVersionCount).toEqual(expectedVersionCount); }); it('can find linuxVersionById', () => { let addedVersionId = linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); var linuxVersion = linuxVersionService.getLinuxVersion(addedVersionId); expect(linuxVersion.name).toEqual('Debian'); expect(linuxVersion.number).toEqual('8.4 Jessie'); }); }); -
import { LinuxVersionService } from '../app/linuxVersionService'; import {describe, it, beforeEach,
expect} from 'angular2/testing'; describe('LinuxVersionService', () => { var linuxVersionService: LinuxVersionService = null; beforeEach(()=>{ linuxVersionService = new LinuxVersionService(); }); it('can add linuxVersion', () => { let expectedVersionCount = linuxVersionService.getCurrentLinuxVersions().length + 1; linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); let actualVersionCount = linuxVersionService.getCurrentLinuxVersions().length; expect(actualVersionCount).toEqual(expectedVersionCount); }); it('can find linuxVersionById', () => { let addedVersionId = linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); var linuxVersion = linuxVersionService.getLinuxVersion(addedVersionId); expect(linuxVersion.name).toEqual('Debian'); expect(linuxVersion.number).toEqual('8.4 Jessie'); }); }); service.spec.ts -
import { LinuxVersionService } from '../app/linuxVersionService'; import {describe, it, beforeEach,
expect} from 'angular2/testing'; describe('LinuxVersionService', () => { var linuxVersionService: LinuxVersionService = null; beforeEach(()=>{ linuxVersionService = new LinuxVersionService(); }); it('can add linuxVersion', () => { let expectedVersionCount = linuxVersionService.getCurrentLinuxVersions().length + 1; linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); let actualVersionCount = linuxVersionService.getCurrentLinuxVersions().length; expect(actualVersionCount).toEqual(expectedVersionCount); }); it('can find linuxVersionById', () => { let addedVersionId = linuxVersionService.addLinuxVersion('Debian', '8.4 Jessie'); var linuxVersion = linuxVersionService.getLinuxVersion(addedVersionId); expect(linuxVersion.name).toEqual('Debian'); expect(linuxVersion.number).toEqual('8.4 Jessie'); }); }); service.spec.ts -
testrunner.html <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>Ng App
Unit Tests</title> <link rel="stylesheet" href="/node_modules/jasmine-core/lib/jasmine-core/jasmine.css"> <script src="/node_modules/es6-shim/es6-shim.min.js"></script> ... <script src="/node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script> <script src="/node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script> <script src="/node_modules/jasmine-core/lib/jasmine-core/boot.js"></script> </head> <body> <script> System.config({ packages: { 'app': {defaultExtension: 'js'} } }); System.import('app/linuxVersionService.spec') .then(window.onload) .catch(console.error.bind(console)); </script> </body> </html> -
index.html detail.ts service.ts [DI] master.ts /Master / Detail[id] bootstrapper.ts main.ts
specs.ts Tests Test Runner