Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Introduction to Angular2

An Introduction to Angular2

Linux Tage Wien (Vienna, Austria)

source code: https://github.com/duffleit/LinuxWochen

SQUER Solutions

April 30, 2016
Tweet

More Decks by SQUER Solutions

Other Decks in Technology

Transcript

  1. Entstehung von JS • 10 Tage • Brendan Eich •

    Standard durch ECMA • Laufzeitumgebung = Browser Mocha LiveScript
  2. Features Angular 2 • Speed & Performance • Simple &

    Expressive • Cross Platorm • Routng • Dependency Injecton
  3. AngularJS 1 -> Angular2 • Ziele mit AngularJs 1 nicht

    erreichbar  Neues Framework • Binding • Dependency Injecton • Modularität • Performance
  4. Typescript • Open Source • Transpilieren zu JavaScript • Source

    Maps • Typen • Module • Typ Inferenz • Klassen, Interfaces
  5. Setup Angular 2 • package.json • Angular 2 dependencies •

    Dev dependencies • tsconfg.json • Confg fle für Typescript
  6. <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
  7. 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
  8. 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
  9. 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
  10. 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"} ] }
  11. 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
  12. 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
  13. 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"} ] }
  14. 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"} ] }
  15. 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"} ] }
  16. 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(); } }
  17. 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(); } }
  18. 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
  19. 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(); } }
  20. 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
  21. 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'
  22. 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 }); } }
  23. 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 }); } }
  24. 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
  25. 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(); } }
  26. 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; }
  27. 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"; }
  28. 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"; }
  29. 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 }]); } }
  30. 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) } }
  31. 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 •…
  32. 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'); }); });
  33. 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
  34. 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
  35. 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>