An Introduction to Angular2

An Introduction to Angular2

Linux Tage Wien (Vienna, Austria)

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

E6c61f085d7aceaf97b7bd00e9195514?s=128

SQUER Solutions

April 30, 2016
Tweet

Transcript

  1. 1.
  2. 3.
  3. 4.

    Entstehung von JS • 10 Tage • Brendan Eich •

    Standard durch ECMA • Laufzeitumgebung = Browser Mocha LiveScript
  4. 9.

    Features Angular 2 • Speed & Performance • Simple &

    Expressive • Cross Platorm • Routng • Dependency Injecton
  5. 10.

    AngularJS 1 -> Angular2 • Ziele mit AngularJs 1 nicht

    erreichbar  Neues Framework • Binding • Dependency Injecton • Modularität • Performance
  6. 11.
  7. 12.

    Typescript • Open Source • Transpilieren zu JavaScript • Source

    Maps • Typen • Module • Typ Inferenz • Klassen, Interfaces
  8. 14.

    Setup Angular 2 • package.json • Angular 2 dependencies •

    Dev dependencies • tsconfg.json • Confg fle für Typescript
  9. 25.
  10. 27.

    <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
  11. 28.

    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
  12. 29.

    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
  13. 30.

    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
  14. 31.

    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"} ] }
  15. 32.

    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
  16. 33.

    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
  17. 34.

    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"} ] }
  18. 35.

    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"} ] }
  19. 36.

    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"} ] }
  20. 37.

    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(); } }
  21. 38.

    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(); } }
  22. 39.

    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
  23. 40.

    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(); } }
  24. 41.

    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
  25. 42.

    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'
  26. 45.

    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 }); } }
  27. 46.

    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 }); } }
  28. 47.

    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
  29. 48.

    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(); } }
  30. 49.

    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; }
  31. 52.

    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"; }
  32. 53.

    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"; }
  33. 54.

    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 }]); } }
  34. 55.

    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) } }
  35. 56.

    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 •…
  36. 60.

    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'); }); });
  37. 61.

    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
  38. 62.

    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
  39. 63.

    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>
  40. 65.