Angular2

Post on 15-Apr-2017

504 views 0 download

Transcript of Angular2

@basti_springer

Agenda• Komponenten

• Module

• Datenfluß

• Direktiven

• Services

• Pipes

• Routing

Wo soll ich denn Anfangen?

Angular CLI

Angular CLI

Angular CLI

Angular CLI

Installiert alle benötigten Abhängigkeiten. Legt eine Projektstruktur an.

Stellt eine Entwicklungsumgebung zur Verfügung.

Kommandos zum Scaffolding. Kommandos zum Bauen der Applikation.

Angular CLI

ng serve: liefert die Applikation auf localhost:4200 aus Proxykonfiguration für Backend möglich.

ng build: baut die Applikation für den Produktivbetrieb

Module

klaas hartz / pixelio.de

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';

@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

Module

declarations: Komponenten und Direktiven imports: Weitere Module importieren providers: Global im Modul verfügbare Services bootstrap: Die Bootstrapping Komponente angeben

Komponenten

designritter / pixelio.de

Komponenten

Grundbaustein einer Applikation. Sind für die Anzeige von Informationen und die Behandlung

von Benutzereingaben zuständig.

Komponenten

Komponenten

Komponentenimport { Component, OnInit } from '@angular/core';

@Component({ selector: 'app-add-list', templateUrl: './add-list.component.html', styleUrls: ['./add-list.component.css'] }) export class AddListComponent implements OnInit {

constructor() { }

ngOnInit() { }

}

Komponenten

Eine Komponente pro Datei.

Pro Komponente ein Verzeichnis.

Dateiname: <Bezeichnung>.component.ts add-list.component.ts

Komponenten

Selektoren prefixen - z.B. mit Applikations-Shortcut.

Komponenten an Elemente binden. Attribute, Klassen und IDs sind zwar möglich, sollte man aber nicht nutzen.

Templates

import { Component } from '@angular/core';

@Component({ selector: 'add-list', template: ‘<div>Hello World</div>‘, }) export class AddListComponent { }

Bei sehr kleinen Komponenten können die Templates inline erzeugt werden. Im Normalfall liegen sie aber in einer eigenen

Datei.

Styles

Angular erlaubt es Styles pro Komponente zu erzeugen. Diese gelten dann nur für die Komponente.

Styles können auch inline oder in einer separaten Datei geschrieben werden

Stylesul { list-style: none; }

Interpolation

Darstellen der Informationen aus der Komponenten-Klasse.

Ändert sich der Wert in der Komponente, wird er in das Template synchronisiert.

Darstellung von Informationen

export class AddListComponent implements OnInit {

private headline = 'Addresslist'; private addresses: Address[];

constructor() { this.addresses = [ {name: 'Peter', street: 'Kirchplatz 2', place: '20095 Hamburg'}, {name: 'Paul', street: 'Sonnenstraße 14', place: '80331 München'} ]; }

ngOnInit() { } }

Lifecycle Hooks

Darstellung von Informationen

Wir arbeiten mit Typescript, also können wir auch Klassen für unsere Datenstrukturen erstellen.

export class Address { constructor( public name: string, public street: string, public place: string, public rating: number) {} }

Direktiven

Struktur Direktiven

verändern die Struktur der View.

ngIf, ngFor

Attribut Direktiven

beeinflussen das Verhalten von Elementen

ngStyle

Die Angular-eigenen Direktiven werden über das BrowserModule zur Verfügung gestellt.

Darstellung von Informationen

<ul> <li *ngFor="let address of addresses"> {{address.name}} - {{address.street}} - {{address.place}} </li> </ul>

DirektivenDer * bei Strukturdirektiven ist eine Shortcut-Form für die

Template-Schreibweise.

Strukturdirektiven nutzen intern HTML5 Template-Tags.

<p *ngIf="condition"> Hello World </p>

<template [ngIf]="condition"> <p> Hello World </p> </template>

Data-BindingTyp Syntax

Interpolation {{value}}

Property-Binding [src]=“logo”

Event-Binding (click)=“hello()”

2 Way Data-Binding [(ng-model)]=“myValue”

Property Binding<img [src]="logo" />

Eigenschaften von Elementen mit dynamischen Werten setzen.

Event-Binding

<button type="button" name="button" (click)="hello($event)">Click me</button>

Die Methode hello der Komponenten-Klasse wird beim Click-Event ausgeführt.

Das $event-Objekt enthält alle Informationen über das Event.

Komponentenhierarchie

Peter Bohot / pixelio.de

Komponentenhierarchie

Eine Angular-Applikation besteht in den meisten Fällen aus einer Hierarchie von Komponenten.

Jede Komponente kann eine oder mehrere Kindkomponenten beinhalten.

Komponentenhierarchie

Eine Kindkomponente wird erstellt, sobald die Elternkomponente zu umfangreich wird,

zu viele Dinge parallel tut oder wenn Elemente an anderen Stellen wiederverwendet

werden sollen.

Komponentenhierarchie

import { Component, OnInit } from '@angular/core';

@Component({ selector: 'app-rating', templateUrl: './rating.component.html', styleUrls: ['./rating.component.css'] }) export class RatingComponent implements OnInit {

constructor() { }

ngOnInit() { }

}

Die Kindkomponente

Komponentenhierarchie

<h1>{{headline}}</h1>

<ul> <li *ngFor="let address of addresses"> {{address.name}} - {{address.street}} - {{address.place}} <app-rating></app-rating> </li> </ul>

Im Template der Elternkomponente:

Datenfluß

Andreas Hermsdorf / pixelio.de

👫 → 👶

Eltern → Kind

Wie kommen die Informationen der Elternkomponente in die Kindkomponente?

Eltern → Kind<app-rating [item]="address"></app-rating>

@Component({ selector: 'app-rating', templateUrl: './app-rating.component.html', styleUrls: ['./app-rating.component.css'] }) export class AppRatingComponent implements OnInit {

@Input() item: RatingItem;

constructor() { }

ngOnInit() { } }

👶 ! 👫

Kind → Eltern

Da die Informationen per Referenz an die Kinder übergeben werden, können diese die Informationen verändern und die

Elternkomponente erhält die Änderungen ebenfalls.

Kind → Eltern

export class AppRatingComponent {

@Input() item: RatingItem;

constructor() { }

rate(value) { this.item.rating = value; } }

Kind → Eltern

Die bessere Lösung: Eventbinding nach außen.

Kind → Eltern

1. Eventemitter in der Kindkomponente implementieren

2. Eventemitter mit dem @Output Decorator kennzeichnen

3. Eventbinding in der Elternkomponente umsetzen

4. Methode zur Behandlung in der Elternkomponente implementieren

Kind → Elternimport { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

import { RatingItem } from '../shared/rating-item';

@Component({…}) export class AppRatingComponent {

@Input() item: RatingItem; @Output() rating = new EventEmitter();

rate(value) { var copy = Object.assign({}, this.item) copy.rating = value; this.rating.emit(copy); } }

Kind → Eltern

<ul> <li *ngFor="let address of addresses"> {{address.name}} - {{address.street}} - {{address.place}} <app-rating [item]="address" (rating)="rating($event)"></app-rating> </li> </ul>

Kind → Elternimport { Component, OnInit } from '@angular/core';

import { Address } from '../shared/address';

@Component({…}) export class AddListComponent implements OnInit {

private addresses: Address[];

constructor() { this.addresses = […]; }

rating(address: Address) { // save to server console.log('saving'); let index = this.addresses.findIndex((el) => { if (el.name === address.name && el.street === address.street && el.place === address.place) { return true; } return false; }); this.addresses[index] = address; } }

Services

Anja Müller / pixelio.de

Service

Services werden zur Auslagerung von Logik verwendet.

Sie können Informationen zur Verfügung stellen oder zur Kommunikation verwendet werden.

Service

1. Service erzeugen

2. Im Modul registrieren

3. Per Dependency Injection einbinden

Service$ ng g service converter

import { Injectable } from '@angular/core';

@Injectable() export class ConverterService {

private dolEur = 0.919337342; private eurDol = 1.08774;

dollarToEuro(dollar) { return dollar * this.dolEur; } euroToDollar(euro) { return euro * this.eurDol; } }

Service… import { ConverterService } from './converter.service';

@NgModule({ declarations: […], imports: […], providers: [ ConverterService ], bootstrap: […] }) export class AppModule { }

Service… import { ConverterService } from '../converter.service';

@Component({…}) export class AddListComponent implements OnInit {

… private value: number;

constructor(private converterService: ConverterService) { this.value = this.converterService.dollarToEuro(15); … } }

Serverkommunikation

Rainer Sturm / pixelio.de

Serverkommunikationimport { Injectable } from '@angular/core'; import { Address } from './shared/address'; import { Http } from '@angular/http'; import 'rxjs/add/operator/toPromise';

@Injectable() export class AddressService {

constructor(public http: Http) { }

get(id: number): Promise<Address> { return this.http.get('/address/' + id) .toPromise() .then(res => { return res.json() as Address; }); } }

Direktiven

Direktiven

1. Direktive erzeugen

2. Als Declaration im Module registrieren

3. Als Attribut einbinden

Direktiven$ ng g directive unless

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[unless]' })

export class UnlessDirective {

constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef ) { }

@Input() set unless(condition: boolean) { if (!condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } }

Direktiven… import { UnlessDirective } from './unless.directive';

@NgModule({ declarations: [ … UnlessDirective ], imports: […], providers: […], bootstrap: […] }) export class AppModule { }

Direktiven

<div *unless="true"> UNLESS TRUE </div>

<div *unless="false"> UNLESS FALSE </div>

Den Stern nicht vergessen, sonst: Error: No provider for TemplateRef!

Pipes

Kurt Michel / pixelio.de

Pipes

Pipes werden verwendet, um eine Eingabe in eine Ausgabe zu transformieren.

Pipes werden hauptsächlich in Templates eingesetzt.

Pipes können parametrisiert werden: value | pipe : ‘a’: ‘b’

Mehrere Pipes können hintereinander geschaltet werden.

Pipes

1. Pipe erzeugen

2. Pipe im Module, im Abschnitt declarations registrieren

3. Pipe im Template nutzen

Pipes$ ng g pipe converter

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'converter' }) export class ConverterPipe implements PipeTransform {

transform(value: any, what: string): any { let multiplier = 1; … return value * multiplier; } }

Pipes… import { ConverterPipe } from './converter.pipe';

@NgModule({ declarations: [ … ConverterPipe ], imports: […], providers: […], bootstrap: […] }) export class AppModule { }

Pipes

Pipe: {{ 15 | converter : 'dollarToEuro' }}

Pipes

Aus Performancegründen gibt es keine OrderBy- und Filter-Pipes in Angular mehr. Diese müssen entweder über externe

Module eingebunden werden oder selbst implementiert werden.

Pipesimport { Pipe, PipeTransform } from '@angular/core'; import {Todo} from "./todo";

@Pipe({ name: 'filter' }) export class FilterPipe implements PipeTransform {

transform(todos: Todo[], args?: any): Todo[] { if (args === 'all') { return todos; } return todos.filter((todo) => { return todo.status == args }); } }

Forms

Timo Klostermeier / pixelio.de

Forms

Angular bietet zahlreiche Hilfestellungen für die Formularbehandlung.

Forms

1. Forms Modul einbinden

2. Formular erstellen

Formsimport { FormsModule } from '@angular/forms';

@NgModule({ declarations: […], imports: [… FormsModule ], providers: […], bootstrap: [AppComponent] }) export class AppModule { }

FormsState Klassen, wenn

zutreffendKlasse, wenn nicht

zutreffend

Element wurde besucht ng-touched ng-untouched

Wert wurde verändert ng-dirty ng-pristine

Wert ist gültig ng-valid ng-invalid

Forms

<input type="text" name="name" [(ngModel)]="value" #name="ngModel">

{{name.pristine}}

Validatoren

Bestehende Validatoren: required, minlength, maxlength, pattern

Eigene Validatoren können über Direktiven implementiert werden.

Routing

Andreas Hermsdorf / pixelio.de

Routing

Routing wird zur Navigation in Single Page-Applikationen verwendet.

Der Angular Router kann verschiedene Komponenten an bestimmten stellen der Applikation einbinden, je nachdem

welche Applikationsstatus aktiviert wird.

Der Applikationsstatus kann über die URL geändert werden.

Routing

1. base href=“/“ setzen

2. Routermodul einbinden

3. Router-Outlet anlegen

4. Routingkonfiguration erstellen

Routingimport { ModuleWithProviders } from '@angular/core'; import { Routes, RouterModule } from '@angular/router';

const appRoutes: Routes = [ { path: '', redirectTo: 'list', pathMatch: 'full' }, { path: 'list', component: ListComponent }, { path: 'form', component: FormComponent }, { path: 'form/:id', component: FormComponent } ];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

Routing… import { routing } from './app.routing';

@NgModule({ declarations: […], imports: [… routing ], providers: […], bootstrap: [AppComponent] }) export class AppModule { }

Routing

<a routerLink="/form">Neuer Datensatz</a>

Im Template kann mit der routerLink-Direktive navigiert werden.

Routing

import { Component, OnInit } from '@angular/core'; import { Router, NavigationExtras } from '@angular/router';

@Component({…}) export class TodoListComponent implements OnInit {

constructor(private router: Router) { }

private create() { this.router.navigate(['/form']) } }

Im Controller wird über die router.navigate-Methode navigiert.

RoutingZugriff auf Variablen.

{ path: 'form/:id', component: FormComponent }

ngOnInit() { this.route.params.forEach((params: Params) => { let id = +params['id'];

… }); }

3rd Party Module

3rd Party Module

Module von Drittanbietern stellen Komponenten, Direktiven, Pipes und Services zur Verfügung.

Sie können in die Applikation eingebunden und verwendet werden.

3rd Party ModuleAngular Material

1. Installation

2. Einbindung

3. Verwendung

3rd Party Module

npm install --save @angular/material

3rd Party Module

import { MaterialModule } from '@angular/material'; @NgModule({ imports: [MaterialModule.forRoot()], … }) export class AppModule { }

3rd Party Module<md-card> <label> Indeterminate progress-bar <md-progress-bar class="app-progress" mode="indeterminate" aria-label="Indeterminate progress-bar example"></md-progress-bar> </label>

<label> Determinate progress bar - {{progress}}% <md-progress-bar class="app-progress" color="accent" mode="determinate" [value]="progress" aria-label="Determinate progress-bar example"></md-progress-bar> </label> </md-card>

3rd Party Module

progress: number = 0;

constructor() {

setInterval(() => { this.progress = (this.progress + Math.floor(Math.random() * 4) + 1) % 100; }, 200); }

3rd Party Module

Fragen?

Rainer Sturm / pixelio.de