SlideShare ist ein Scribd-Unternehmen logo
Basti
• Sebastian Springer
• aus München
• arbeite bei MaibornWolff GmbH
• https://github.com/sspringer82
• @basti_springer
• JavaScript Entwickler
ngModule ngModule
router
Component Service
Template
Styles
DataBinding
Pipe Directive
Compon
ent
DI
PropertyBinding
EventBinding
importsroot module
Application
Angular
Angular ist ein JavaScript-Framework, das von Google
entwickelt wurde. Es ist Open Source und wird auf GitHub
maintained.
Das Projekt selbst ist in mehrere Module unterteilt, sodass
man lediglich die Module laden muss, die für einen selbst
relevant sind.
Alle Module werden parallel entwickelt und wiesen die gleiche
Versionsnummer auf.
Angular setzt mittlerweile auf Semantic Versioning. Es gibt
zweimal im Jahr ein neues Major-Release
Angular
Aktuelle Version: 6.0.x
Dokumentation: https://angular.io/docs/ts/latest/
Style Guide: https://angular.io/docs/ts/latest/guide/style-
guide.html
TypeScript
TypeScript
Das Entwickler Team von Angular hat sich dazu entschieden
ein Typsystem für JavaScript einzusetzen. Ursprünglich
wurde mit AtScript eine eigene Lösung entwickelt. Während
der Entwicklung wurde auf TypeScript geschwenkt.
TypeScript bietet statische Typenprüfung, die Verwendung
von Interfaces und einen Transpiler der moderne JavaScript-
Features auch für ältere Browser verfügbar macht.
TypeScript
Der TypeScript Compiler (tsc) wandelt den TypeScript-Code
in JavaScript um, das vom Browser ausgeführt wird.
Eine TypeScript-Datei endet per Konvention auf .ts.
Dem Compiler können über eine Konfigurationsdatei
(tsconfig.json) bestimmte Einstellungen mitgegeben werden.
Liegt einen Bibliothek nicht in TypeScript vor, können
Typdefinitionen heruntergeladen und installiert werden (http://
definitelytyped.org/)
TypeScript
Die Kernfeatures von TypeScript sind:
• Datentypen (primitive und composite)
• Typsichere Funktionen (Parameterliste und Rückgabewert)
• Klassen, Interfaces und Generics
TypeScript
import { Person } from './person';
export class User extends Person {
private password: string;
constructor(public name: string) {
super(name);
}
public setPassword(password: string) {
this.password = this.createHash(password);
}
private createHash(input: string): string {...}
}
CLI
CLI
Um den Start in eine Angular Applikation so einfach wie
möglich zu machen, gibt es das Angular-CLI-Tool.
Dieses Werkzeug kommt im gesamten Lebenszyklus zum
Einsatz von der Erstellung des Projekts, über die
Entwicklung des Quellcodes bis zum Bau der fertigen
Applikation für den Produktivbetrieb.
CLI
npm install -g @angular/cli
CLI
Die wichtigsten Kommandos:
Neues Projekt anlegen:
ng new <Projekt>
Neues Element (z.B. Component) erzeugen:
ng generate <blueprint> <Bezeichnung>
Dev Server starten:
ng serve
Applikation bauen
ng build
Elemente
Tim Reckmann / pixelio.de
Elemente
• Module
• Component
• Service
• Directive
• Pipe
Module
Container-Element in der Applikation. Es fasst
zusammengehörige Components, Services, etc. zusammen.
Eine Applikation kann mehrere Module importieren.
Component
Baustein einer Applikation. Eine Component besteht aus
Metainformationen, einem Template und einer Klasse.
Eine Applikation setzt sich aus einem Baum von
Komponenten zusammen.
Service
Services dienen zur Datenhaltung und zur Kapselung von
Logik.
Directive
Directives wirken sich auf das Verhalten und die Struktur des
DOM aus. Sie kommen in den Templates einer Applikation vor.
Eine Component ist eine Sonderform der Directive, da sie ein
eigenes Template aufweist.
Pipe
Mit einer Pipe lässt sich eine gegebene Eingabe nach
bestimmten Regeln in einen Ausgabe transformieren.
Sie dienen vor allem der Anpassung von Anzeigewerten.
Module
C. Nöhren / pixelio.de
Module
Das App-Modul ist der Einstiegspunkt in die Applikation. Es
gibt an, welche weiteren Module importiert werden, welche
Components und Services verfügbar sind und welche
Component die Wurzel der Applikation bildet.
Das App Module wird initial vom CLI erzeugt
Module
import { … } from ‘…’;
@NgModule({
declarations: […],
imports: […],
providers: […],
bootstrap: [AppComponent]
})
export class AppModule { }
• declarations: Registrierung 

von Components
• imports: Importieren von 

Modulen
• providers: Registrierung von 

Services
• bootstrap: Root Component
Component
Verena N. / pixelio.de
Component
Erzeugung:
ng generate component HelloWorld
Es wird ein Verzeichnis mit folgendem Inhalt erzeugt:
src/app/hello-world/
├── hello-world.component.css
├── hello-world.component.html
├── hello-world.component.spec.ts
└── hello-world.component.ts
Die Component wird automatisch im Module registriert
Component
import { Component } from '@angular/core';
@Component({
selector: 'app-hello-world',
templateUrl: './hello-world.component.html',
styleUrls: ['./hello-world.component.css']
})
export class HelloWorldComponent {
constructor() { }
}
Component
Der grundlegende Aufbau einer Component ist:
• Imports aller benötigten Dateien
• Decorator mit Metadaten der Component
• Component Class
Der Selector gibt den Tag-Namen an über den die
Component eingebunden wird.
Die Component-Klasse dient der Datenhaltung für das
Template und stellt Methoden zur Verfügung.
Styling
knipseline / pixelio.de
Styling
Standardmäßig gelten die in einer Component definierten
Styles nur für die Component. Diese Lösung wird durch das
Umbenennen der CSS-Klassen gelöst.
Über die encapsulation-Eigenschaft des Decorators können
auch andere Modi verwendet werden:
• Native: Der Shadow-DOM wird verwendet
• Emulated: CSS Renaming (Standard)
• None: Keine Kapselung, Styles gelten global
Template
S. Hofschlaeger / pixelio.de
Template
Angular nutzt HTML als Template-Engine. Templates können
entweder inline im Decorator einer Component definiert
werden oder in einer separaten HTML-Datei, was die
Empfohlene Lösung ist.
Per Interpolation ({{}}) kann vom Template aus auf die
Eigenschaften der Component-Klasse zugegriffen werden.
Templates
import { Component } from '@angular/core';
@Component({
selector: 'app-list',
templateUrl: './list.component.html',
styleUrls: ['./list.component.css']
})
export class ListComponent {
name: string;
constructor() {
this.name = 'Klaus';
}
}
<h1>Hello {{name}}</h1>
list/list.component.ts
list/list.component.html
Event-Binding
Rike / pixelio.de
Event-Binding
Ähnlich wie auf Eigenschaften kann auch auf Methoden der
Component-Class zugegriffen werden.
(click)=“handleClick()”
Mit dem Event-Binding wird beim Auslösen des Events z.B.
eines Klicks die verbundene Methode der Component-Class
aufgerufen. Dieser Methode können Eigenschaften übergeben
werden.
Mit der $event-Variablen erhält die Methode eine Referenz auf
das Event-Objekt.
Event-Binding
export class ListComponent {
greeting = '';
greetMe(event, name) {
console.log(event);
this.greeting = `Hello ${name}`;
}
}
<button (click)="greetMe($event, 'Klaus')">
greet me
</button>
{{greeting}}
list.component.html
list.component.ts
Lifecycle
redsheep / pixelio.de
Lifecycle
Im Lebenszyklus einer Component gibt es verschiedene
Phase. Für jede dieser Phasen gibt es einen Hook, für den
man eine Funktion definieren kann.
Vorgehensweise:
• Interface implementieren
• Hook-Methode umsetzen
import { Component, OnInit } from '@angular/core';
@Component({…})
export class ListComponent implements OnInit {
ngOnInit() {
// initialization here
}
}
Lifecycle
Wird bei der Erzeugung ausgeführt
Auf eingehende Datenänderungen reagieren
Initialisierung (wird nur 1x aufgerufen)
Wird bei der Change Detection aufgerufen
Nachdem externer Inhalt verarbeitet wurde
Reaktionsmöglichkeit auf Inhaltsprüfungen
Reaktionsmöglichkeit auf Initialisierung
Hook nach View und View Children
Wird vor der Zerstörung aufgerufen
Child Components
Alexandra H. / pixelio.de
Child Components
Eine Angular-Applikation besteht aus einem Baum von
Components. In einem Template einer Component können
beliebig viele Child Components referenziert werden.
Diese Art der Strukturierung erhöht die
Wiederverwendbarkeit einzelner Teile der Appliktion.
Außerdem wird durch definierte Schnittstellen eine lose
Kopplung zwischen den einzelnen Components geschaffen.
Child Components
ng generate component list-item
Component auf der Kommandozeile erzeugen
Component in app.module.ts (declarations) registrieren
(automatisch)
Component verwenden (list.component.html)
<ul>
<app-list-item *ngFor="let item of items"></app-list-item>
</ul>
Child Component - Input
Um Informationen in eine Child Component hinein zu reichen,
wird das Angular Property Binding ([]) in Verbindung mit
Input Binding (@Input) verwendet. Achtung: auf @Input folgen
immer Klammern.
<ul>
<app-list-item *ngFor="let item of items" [item]="item">
</app-list-item>
</ul>
@Component({…})
export class ListItemComponent {
@Input()
item: Item;
constructor() { }
}
Child Component - Output
Die Informationen, die per Input-Binding in eine Child
Component hineingegeben werden, sollten nicht by
Reference verändert werden. Werden die Daten angepasst,
passiert dies auf einer Kopie der Daten und die Parent
Component wird per Event benachrichtigt.
1. Output Binding festlegen
2. Eventhandler erzeugen und emit-Methode aufrufen
3. In der Eltern Component auf das Event reagieren

Der Zugriff auf die Event-Daten erfolgt über die $event-
Variable
Output - Child Component
<li>
{{item.title}}
<a (click)="delete(item.title)">remove</a>
</li>
@Component({
selector: 'app-list-item',
templateUrl: './list-item.component.html',
styleUrls: ['./list-item.component.css']
})
export class ListItemComponent {
@Output()
public onDelete = new EventEmitter();
…
delete(title) {
this.onDelete.emit(title);
}
}
Output - Parent Component
<ul>
<app-list-item
*ngFor="let item of items"
[item]="item"
(onDelete)="removeItem($event)">
</app-list-item>
</ul>
export class ListComponent implements OnInit {
…
removeItem(title) {
const index = this.items.findIndex(
item => item.title === title
);
this.items.splice(index, 1);
}
}
Pipes
marge simpson / pixelio.de
Pipes
Pipes werden verwendet, um Anzeigewerte zu formatieren.
Pipes sind Datenstreams mit Eingabe, Ausgabe und
Parametern. Mit den Parametern kann das Verhalten der
Pipe beeinflusst werden.
Eine Pipe wird durch das | vom Eingangswert getrennt. Die
Parameter werden durch Doppelpunkte getrennt.
Mehrere Pipes können miteinander verkettet werden. Sie
werden ebenfalls durch das |-Zeichen voneinander getrennt.
Die Ausgabe einer Pipe dient dann als Eingabe für die
nachfolgende.
Pipes
export class ListComponent implements OnInit {
date = Date.now();
…
}
<div>It's {{ date | date: 'shortTime' }}</div>
RxJS
RxJS
Die Reactive Extensions sind eine Bibliothek, die eine
Implementierung des Observer-Patterns darstellen. Damit
wird asynchrone Programmierung über definierte
Schnittstellen möglich. Reactive Extensions sind wesentlich
flexibler als Callback-Funktionen und Promises.
Reactive Extensions wurden von Microsoft entwickelt und
sind für viele Sprachen wie Java, C#, C++ oder JavaScript
verfügbar.
Observable
Change
Observer
Subscribe
Notify
Operatoren
Operatoren sind die Werkzeugkiste von RxJS.
Operatoren erfüllen verschiedene Zwecke: Sie können
verwendet werden, um Observables zu erzeugen,
Datenströme zu Filtern oder Fehler in der Applikation zu
behandeln.
Operatoren
range(1, 10)
.pipe(
filter(x => x % 2 === 0)
)
.subscribe(x => console.log(x));
RxJS in Components
import { Component, OnInit } from '@angular/core';
import { interval } from ‘rxjs';
import { timestamp, map } from ‘rxjs/operators’;
@Component({…})
export class DateComponent implements OnInit {
private timestamp: number;
ngOnInit() {
interval(1000)
.pipe(
timestamp(),
map(ts => ts.timestamp)
)
.subscribe(ts => {
this.timestamp = ts;
});
}
}
Services
Niko Korte / pixelio.de
Services
Services kapseln Logik und können zur Datenverwaltung
verwendet werden. Mit Services kann außerdem mit anderen
Systemen kommuniziert werden.
Angular gibt für Services keine Struktur vor.
Services
ng generate service user
Dieser Befehl erzeugt einen Service. Dieser muss
anschließend noch als Provider registriert werden. Hierfür
gibt es zwei Möglichkeiten:
• Am Modul: Das gesamte Modul (app.module.ts unter dem
Schlüssel provider) teilt sich eine Instanz des Services
• An einer bestimmten Component: Eine Instanz pro
Component (Component-Datei im @Component-Decorator
als provider)
import { Injectable } from '@angular/core';
import { User } from './user';
@Injectable()
export class UserService {
users: Array<User> = [];
constructor() { }
load() {
this.users.push({id: 1, name: 'Peter'});
this.users.push({id: 2, name: 'Paul'});
this.users.push({id: 3, name: 'Mary'});
}
get() {
return this.users;
}
add(user: User) {
this.users.push(user);
}
update(user: User) {
const index = this.users.findIndex(existingUser => existingUser.id === user.id);
this.users[index] = user;
}
remove(id: number) {
const index = this.users.findIndex(user => user.id === id);
this.users.splice(index, 1);
}
}
Dependency Injection
Rainer Sturm / pixelio.de
Dependency Injection
Bevor ein Service verwendet werden kann, muss er zunächst
geladen werden. Dies geschieht über die Dependency
Injection von Angular. Im einfachsten Fall werden die
Abhängigkeiten zu anderen Elementen der Applikation im
Konstruktor einer Klasse angegeben. Angular sucht
daraufhin nach einem passenden Provider und liefert
entweder eine bestehende Instanz aus dem Cache aus oder
erzeugt eine neue Instanz.
Dependency Injection
export class ListComponent implements OnInit {
users: Array<User> = [];
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.load();
this.users = this.userService.get();
}
removeUser(id) {
this.userService.remove(id);
this.users = this.userService.get();
}
}
HTTP
Angela Parszyk / pixelio.de
HTTP
Der http Service ist ein separates Modul des Angular-
Frameworks. Er dient der Kommunikation mit einem
Webserver und kann per Dependency Injection sowohl von
anderen Services als auch direkt in Components verwendet
werden.
1. HttpClientModule in app.module.ts als imports einbinden
(@angular/common/http)
2. HttpClient per Dependency Injection laden
3. Instanz verwenden.
HTTP
import { Injectable } from '@angular/core';
import { HttpClient } from ‘@angular/common/http';
import { User } from './user';
import 'rxjs/add/operator/map';
@Injectable()
export class UserService {
users: Array<User> = [];
constructor(private http: HttpClient) {}
load() {
this.http.get('/user')
.subscribe((users: Array<User>) => {
this.users = users;
});
}
}
HTTP
Die Methoden des HttpService geben keine Promise,
sondern ein RxJS-Observable zurück. Bei diesem Objekt
handelt es sich um einen asynchronen Datenstrom auf den
verschiedene Operatoren wie z.B. map angewendet werden
können. Mit der subscribe-Methode können Sie eine
Callback-Funktion registrieren.
HTTP
Wird bei der Entwicklung ng serve verwendet, kann die
proxy-Option von Webpack eingesetzt werden, um Anfragen
an den Server auf einen anderen Port umzuleiten. Damit kann
ein Backend an die, sich im Entwicklungsbetrieb
befindende, Applikation angeschlossen werden, ohne dass
Anpassungen am Quellcode erforderlich sind.
Reactive Stores
Rainer Sturm / pixelio.de
Reactive Store
Ein Reactive Store kapselt die Datenhaltung in einer internen
Datenstruktur. Der Store wird nicht direkt sondern über eine
definierte API modifiziert. Meist ist der Store mit dem HTTP-
Service verbunden.
Der Store selbst ist als Service umgesetzt, der in Components
per Dependency Injection eingebunden wird.
Die API verfügt meist über Methoden für CRUD-Operationen.
Reactive Store
@Injectable()
export class TodoService {
todos: Observable<Todo[]>
private _todos: BehaviorSubject<Todo[]>;
private baseUrl: string;
private dataStore: {
todos: Todo[]
};
constructor() {
this.dataStore = { todos: [] };
this._todos = <BehaviorSubject<Todo[]>>new
BehaviorSubject([]);
this.todos = this._todos.asObservable();
}
}
Reactive Store
Das Observable dient als readonly-Schnittstelle nach außen.
Intern werden Veränderungen über das BehaviorSubject
publiziert. Im internen dataStore werden die Daten
vorgehalten.
In das BehaviorSubject können sowohl Daten geschrieben
werden als auch gelesen werden. Außerdem kann es als
Observable exportiert werden.
Reactive Store
create(todo: Todo) {
this.dataStore.todos.push(todo);
this._todos.next(Object.assign({}, this.dataStore).todos);
}
Operationen auf dem Store laufen immer nach dem gleichen
Schema ab: Zuerst wird der lokale DataStore modifiziert,
danach die next-Methode des BehaviorSubjects mit einem
Klon des DataStores aufgerufen.
Forms
Bernd Kasper / pixelio.de
Forms
Angular verfügt über zwei Arten von Formularen: Template
Driven Forms und Reactive Forms.
Template Driven Forms sind einfacher und basieren
hauptsächlich auf Templates. Reactive Forms sind flexibler
und erfordern mehr TypeScript-Quellcode.
Template Driven Forms
1. Form Modul einbinden
2. Component erstellen
3. Template erzeugen
4. Formular-Elemente mit ngModel anbinden
5. name-Attribute einfügen
6. Validierung umsetzen
7. Formular abschicken
Template Driven Forms
Das Forms Modul stellt Direktiven wie ngModel und ngForm
zur Verfügung, die zur Erzeugung von Formularen erforderlich
sind.
Template Driven Forms
<label for="name">Name</label>
<input type="text" class="form-control" id="name" required
[(ngModel)]="model.name" name="name">
Das id-Attribut wird zur Verknüpfung mit dem label
verwendet. Das name-Attribut und die ngModel-Direktive
dienen der Formularbehandlung durch Angular. Das
required-Attribut ist eine Direktive, die einen Validator
aktiviert.
Durch ngModel werden die Werte direkt mit dem Model der
Component synchronisiert.
Template Driven Forms
State Wahr falsch
Element wurde
besucht
ng-touched ng-untouched
Wert hat sich geändert ng-dirty ng-pristine
Wert ist gültig ng-valid ng-invalid
Auf den Status eines Form-Elements kann zugegriffen
werden. Angular trackt verschiedene States als CSS-Klassen.
Damit können Styles angewendet werden.
Template Driven Forms
<div [hidden]="name.valid || name.pristine"
class=“error-message“>
Name is required
</div>
Über den Namen des Eingabefeldes kann auch auf dessen
Status zugegriffen werden und so z.B. Fehlermeldungen
ein- beziehungsweise ausgeblendet werden.
Template Driven Forms
Das Formular kann mit der ngSubmit-Direktive abgesendet
werden. Diese wird direkt an das Formular gebunden.
Sobald das Formular über den Submit-Button abgesendet
wird, wird die onSubmit-Methode der Component aufgerufen.
Durch das disabled-Attribut wird der Submit-Button erst
verfügbar, sobald das Formular valide ist.
<form (ngSubmit)="onSubmit()" #addressForm="ngForm">
…
<button type="submit" class="btn btn-success" [disabled]="!
addressForm.form.valid">Submit</button>
</form>
Reactive Forms
Damit Sie Reactive Forms benutzen können, müssen Sie in
Ihrem Root-Module das ReactiveFormsModule einbinden
(per Imports).
Danach erzeugen Sie in Ihrem Template die Struktur. Die
Verbindung zum Formular erfolgt hier über die
formControlName-Direktive.
Alles Weitere geschieht im Code der Component. Hier
verwenden Sie den FormBuilder, um das Formular zu
erzeugen.
Reactive Forms
export class FormComponent implements OnInit {
form: FormGroup;
constructor(fb: FormBuilder) {
this.form = fb.group({
"name": ["", Validators.required],
"password":["", Validators.required]
});
}
ngOnInit() {
this.form.valueChanges
.map((value) => {
value.name = value.name.toUpperCase();
return value;
})
.filter((value) => this.form.valid)
.subscribe((value) => {…});
}
}
Reactive Forms
<section class="sample-app-content">
<h1>Model-based Form Example:</h1>
<form [formGroup]="form">
<p>
<label>Name:</label>
<input type="text" formControlName="name">
</p>
<p>
<label>Password:</label>
<input type="password"
formControlName="password">
</p>
<p>
<button type="submit" [disabled]="!
form.valid">Submit</button>
</p>
</form>
</section>
Routing
Betty / pixelio.de
Routing
Routing bezeichnet die Navigation innerhalb einer Single
Page Applikation über URLs. Eine Änderung der URL sorgt
dabei nicht für einen Page Load, sodass der State der
Applikation erhalten bleibt.
Angular verfügt über ein eigenes Modul zu diesem Zweck:
den Angular Router. Dieses Modul wird standardmäßig von
der Angular CLI mit installiert.
Routing
Damit der Router funktionieren, müssen Sie in Ihrer index.html-
Datei das Tag <base href=“/"> einfügen.
Danach konfigurieren Sie Ihre Routen und registrieren diese in
Ihrem Module.
Routing
import { RouterModule, Routes } from '@angular/router';
const appRoutes: Routes = [
{ path: 'list', component: ListComponent },
{ path: 'address/:id', component: AddressComponent }
];
@NgModule({
declarations: […],
imports: [
RouterModule.forRoot(appRoutes)
…
],
providers: […],
bootstrap: [AppComponent]
})
export class AppModule { }
Routing
Sie können in Ihrer Routing-Konfiguration auch eine
Standardroute für den Einstieg in Ihre Applikation definieren.
{ path: '',
redirectTo: '/list',
pathMatch: 'full'
}
Routing
Je nachdem welche Route Sie in Ihrer Applikation aktivieren,
wird ein anderer Component-Baum angezeigt. Mit dem
RouterOutlet geben Sie an, wo diese Components angezeigt
werden sollen.
<router-outlet></router-outlet>
Routing
Innerhalb Ihrer Applikation können Sie entweder über
RouterLinks oder aus dem Quellcode Ihrer Components
heraus navigieren.
<a routerLink="/list" routerLinkActive="active">Liste</a>
routerLinkActive hilft die aktive Route visuell zu kennzeichnen.
export class ListComponent {
constructor(private router: Router) { }
onShowDetails(address) {
this.router.navigate(['/address', address.id])
}
}
Routing
Routen können sowohl statische als auch dynamische Teile
beinhalten. Auf diese dynamischen Inhalte können Sie über
ein Observable (route.params) zugreifen.
export class AddressComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private service: AddressService
) {}
ngOnInit() {
this.route.params
.switchMap((params: Params) =>
this.service.get(parseInt(params['id']))
.subscribe((add: Address) => this.add = add);
}
}
Fragen?
Rainer Sturm / pixelio.de
KONTAKT
Sebastian Springer
sebastian.springer@maibornwolff.de
MaibornWolff GmbH
Theresienhöhe 13
80339 München
@basti_springer
https://github.com/sspringer82

Weitere ähnliche Inhalte

Ähnlich wie Schnelleinstieg in Angular

Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...Andreas Wissel
 
Angular 2 Workshop November 2015 von der w-jax 2015
Angular 2 Workshop November 2015 von der w-jax 2015Angular 2 Workshop November 2015 von der w-jax 2015
Angular 2 Workshop November 2015 von der w-jax 2015Manfred Steyer
 
B1 Acocon Lotus Day 08.09.2009
B1 Acocon Lotus Day 08.09.2009B1 Acocon Lotus Day 08.09.2009
B1 Acocon Lotus Day 08.09.2009Andreas Schulte
 
Wiederverwendbare Komponenten mit Angular 2.0 – Deep Dive
Wiederverwendbare Komponenten mit Angular 2.0 – Deep DiveWiederverwendbare Komponenten mit Angular 2.0 – Deep Dive
Wiederverwendbare Komponenten mit Angular 2.0 – Deep DiveManfred Steyer
 
Model Driven Development mit Eclipse
Model Driven Development mit EclipseModel Driven Development mit Eclipse
Model Driven Development mit EclipseAndreas Schreiber
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzeRalf Lütke
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Joachim Baumann
 
Einführung in ASP.NET Core Middlewares
Einführung in ASP.NET Core MiddlewaresEinführung in ASP.NET Core Middlewares
Einführung in ASP.NET Core MiddlewaresMatthias Jauernig
 
EnterJS 2015 - JavaScript von Morgen schon heute
EnterJS 2015 - JavaScript von Morgen schon heuteEnterJS 2015 - JavaScript von Morgen schon heute
EnterJS 2015 - JavaScript von Morgen schon heutePhilipp Burgmer
 
Softwerkskammer Chemnitz Special Pecha Kucha Night
Softwerkskammer Chemnitz Special Pecha Kucha NightSoftwerkskammer Chemnitz Special Pecha Kucha Night
Softwerkskammer Chemnitz Special Pecha Kucha NightChristinaLerch1
 
.NET Summit 2016 München: Angular 2 mit TypeScript
.NET Summit 2016 München: Angular 2 mit TypeScript.NET Summit 2016 München: Angular 2 mit TypeScript
.NET Summit 2016 München: Angular 2 mit TypeScriptManfred Steyer
 
Angular 2: Neuerungen und Migration
Angular 2: Neuerungen und MigrationAngular 2: Neuerungen und Migration
Angular 2: Neuerungen und MigrationManfred Steyer
 
Angular 2: Custom Components
Angular 2: Custom ComponentsAngular 2: Custom Components
Angular 2: Custom ComponentsManfred Steyer
 
Komponenten mit Angular 2, Deep Dive
Komponenten mit Angular 2, Deep DiveKomponenten mit Angular 2, Deep Dive
Komponenten mit Angular 2, Deep DiveManfred Steyer
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in RailsAngelo Maron
 

Ähnlich wie Schnelleinstieg in Angular (20)

react-de.pdf
react-de.pdfreact-de.pdf
react-de.pdf
 
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
Robuste Design Systems mit Storybook und Angular: vom Konzept zur lebendigen ...
 
Angular 2 Workshop November 2015 von der w-jax 2015
Angular 2 Workshop November 2015 von der w-jax 2015Angular 2 Workshop November 2015 von der w-jax 2015
Angular 2 Workshop November 2015 von der w-jax 2015
 
B1 Acocon Lotus Day 08.09.2009
B1 Acocon Lotus Day 08.09.2009B1 Acocon Lotus Day 08.09.2009
B1 Acocon Lotus Day 08.09.2009
 
Wiederverwendbare Komponenten mit Angular 2.0 – Deep Dive
Wiederverwendbare Komponenten mit Angular 2.0 – Deep DiveWiederverwendbare Komponenten mit Angular 2.0 – Deep Dive
Wiederverwendbare Komponenten mit Angular 2.0 – Deep Dive
 
Model Driven Development mit Eclipse
Model Driven Development mit EclipseModel Driven Development mit Eclipse
Model Driven Development mit Eclipse
 
MVVM mit WPF
MVVM mit WPFMVVM mit WPF
MVVM mit WPF
 
PHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-AnsätzePHP-Module in statischen Seiten - Architektur-Ansätze
PHP-Module in statischen Seiten - Architektur-Ansätze
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)
 
Einführung in ASP.NET Core Middlewares
Einführung in ASP.NET Core MiddlewaresEinführung in ASP.NET Core Middlewares
Einführung in ASP.NET Core Middlewares
 
Workshop Vue js
Workshop Vue jsWorkshop Vue js
Workshop Vue js
 
EnterJS 2015 - JavaScript von Morgen schon heute
EnterJS 2015 - JavaScript von Morgen schon heuteEnterJS 2015 - JavaScript von Morgen schon heute
EnterJS 2015 - JavaScript von Morgen schon heute
 
Softwerkskammer Chemnitz Special Pecha Kucha Night
Softwerkskammer Chemnitz Special Pecha Kucha NightSoftwerkskammer Chemnitz Special Pecha Kucha Night
Softwerkskammer Chemnitz Special Pecha Kucha Night
 
.NET Summit 2016 München: Angular 2 mit TypeScript
.NET Summit 2016 München: Angular 2 mit TypeScript.NET Summit 2016 München: Angular 2 mit TypeScript
.NET Summit 2016 München: Angular 2 mit TypeScript
 
imatics FormEngine
imatics FormEngineimatics FormEngine
imatics FormEngine
 
AngularJs
AngularJsAngularJs
AngularJs
 
Angular 2: Neuerungen und Migration
Angular 2: Neuerungen und MigrationAngular 2: Neuerungen und Migration
Angular 2: Neuerungen und Migration
 
Angular 2: Custom Components
Angular 2: Custom ComponentsAngular 2: Custom Components
Angular 2: Custom Components
 
Komponenten mit Angular 2, Deep Dive
Komponenten mit Angular 2, Deep DiveKomponenten mit Angular 2, Deep Dive
Komponenten mit Angular 2, Deep Dive
 
Domain Driven Design in Rails
Domain Driven Design in RailsDomain Driven Design in Rails
Domain Driven Design in Rails
 

Mehr von Sebastian Springer

HTMX - ist das die nächste Revolution im Web?
HTMX - ist das die nächste Revolution im Web?HTMX - ist das die nächste Revolution im Web?
HTMX - ist das die nächste Revolution im Web?Sebastian Springer
 
Creating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.jsCreating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.jsSebastian Springer
 
Divide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsDivide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsSebastian Springer
 
From Zero to Hero – Web Performance
From Zero to Hero – Web PerformanceFrom Zero to Hero – Web Performance
From Zero to Hero – Web PerformanceSebastian Springer
 
Von 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im WebVon 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im WebSebastian Springer
 
ECMAScript 6 im Produktivbetrieb
ECMAScript 6 im ProduktivbetriebECMAScript 6 im Produktivbetrieb
ECMAScript 6 im ProduktivbetriebSebastian Springer
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptSebastian Springer
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtSebastian Springer
 

Mehr von Sebastian Springer (20)

HTMX - ist das die nächste Revolution im Web?
HTMX - ist das die nächste Revolution im Web?HTMX - ist das die nächste Revolution im Web?
HTMX - ist das die nächste Revolution im Web?
 
Creating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.jsCreating Enterprise Web Applications with Node.js
Creating Enterprise Web Applications with Node.js
 
Divide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.jsDivide and Conquer – Microservices with Node.js
Divide and Conquer – Microservices with Node.js
 
From Zero to Hero – Web Performance
From Zero to Hero – Web PerformanceFrom Zero to Hero – Web Performance
From Zero to Hero – Web Performance
 
Von 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im WebVon 0 auf 100 - Performance im Web
Von 0 auf 100 - Performance im Web
 
A/B Testing mit Node.js
A/B Testing mit Node.jsA/B Testing mit Node.js
A/B Testing mit Node.js
 
Einführung in React
Einführung in ReactEinführung in React
Einführung in React
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
ECMAScript 6 im Produktivbetrieb
ECMAScript 6 im ProduktivbetriebECMAScript 6 im Produktivbetrieb
ECMAScript 6 im Produktivbetrieb
 
Streams in Node.js
Streams in Node.jsStreams in Node.js
Streams in Node.js
 
JavaScript Performance
JavaScript PerformanceJavaScript Performance
JavaScript Performance
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Node.js Security
Node.js SecurityNode.js Security
Node.js Security
 
Typescript
TypescriptTypescript
Typescript
 
Reactive Programming
Reactive ProgrammingReactive Programming
Reactive Programming
 
Best Practices für TDD in JavaScript
Best Practices für TDD in JavaScriptBest Practices für TDD in JavaScript
Best Practices für TDD in JavaScript
 
Warum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser machtWarum ECMAScript 6 die Welt ein Stückchen besser macht
Warum ECMAScript 6 die Welt ein Stückchen besser macht
 
Lean Startup mit JavaScript
Lean Startup mit JavaScriptLean Startup mit JavaScript
Lean Startup mit JavaScript
 
Webapplikationen mit Node.js
Webapplikationen mit Node.jsWebapplikationen mit Node.js
Webapplikationen mit Node.js
 
Node.js für Webapplikationen
Node.js für WebapplikationenNode.js für Webapplikationen
Node.js für Webapplikationen
 

Schnelleinstieg in Angular

  • 1.
  • 2. Basti • Sebastian Springer • aus München • arbeite bei MaibornWolff GmbH • https://github.com/sspringer82 • @basti_springer • JavaScript Entwickler
  • 3. ngModule ngModule router Component Service Template Styles DataBinding Pipe Directive Compon ent DI PropertyBinding EventBinding importsroot module Application
  • 4. Angular Angular ist ein JavaScript-Framework, das von Google entwickelt wurde. Es ist Open Source und wird auf GitHub maintained. Das Projekt selbst ist in mehrere Module unterteilt, sodass man lediglich die Module laden muss, die für einen selbst relevant sind. Alle Module werden parallel entwickelt und wiesen die gleiche Versionsnummer auf. Angular setzt mittlerweile auf Semantic Versioning. Es gibt zweimal im Jahr ein neues Major-Release
  • 5. Angular Aktuelle Version: 6.0.x Dokumentation: https://angular.io/docs/ts/latest/ Style Guide: https://angular.io/docs/ts/latest/guide/style- guide.html
  • 7. TypeScript Das Entwickler Team von Angular hat sich dazu entschieden ein Typsystem für JavaScript einzusetzen. Ursprünglich wurde mit AtScript eine eigene Lösung entwickelt. Während der Entwicklung wurde auf TypeScript geschwenkt. TypeScript bietet statische Typenprüfung, die Verwendung von Interfaces und einen Transpiler der moderne JavaScript- Features auch für ältere Browser verfügbar macht.
  • 8. TypeScript Der TypeScript Compiler (tsc) wandelt den TypeScript-Code in JavaScript um, das vom Browser ausgeführt wird. Eine TypeScript-Datei endet per Konvention auf .ts. Dem Compiler können über eine Konfigurationsdatei (tsconfig.json) bestimmte Einstellungen mitgegeben werden. Liegt einen Bibliothek nicht in TypeScript vor, können Typdefinitionen heruntergeladen und installiert werden (http:// definitelytyped.org/)
  • 9. TypeScript Die Kernfeatures von TypeScript sind: • Datentypen (primitive und composite) • Typsichere Funktionen (Parameterliste und Rückgabewert) • Klassen, Interfaces und Generics
  • 10. TypeScript import { Person } from './person'; export class User extends Person { private password: string; constructor(public name: string) { super(name); } public setPassword(password: string) { this.password = this.createHash(password); } private createHash(input: string): string {...} }
  • 11. CLI
  • 12. CLI Um den Start in eine Angular Applikation so einfach wie möglich zu machen, gibt es das Angular-CLI-Tool. Dieses Werkzeug kommt im gesamten Lebenszyklus zum Einsatz von der Erstellung des Projekts, über die Entwicklung des Quellcodes bis zum Bau der fertigen Applikation für den Produktivbetrieb.
  • 13. CLI npm install -g @angular/cli
  • 14. CLI Die wichtigsten Kommandos: Neues Projekt anlegen: ng new <Projekt> Neues Element (z.B. Component) erzeugen: ng generate <blueprint> <Bezeichnung> Dev Server starten: ng serve Applikation bauen ng build
  • 16. Elemente • Module • Component • Service • Directive • Pipe
  • 17. Module Container-Element in der Applikation. Es fasst zusammengehörige Components, Services, etc. zusammen. Eine Applikation kann mehrere Module importieren.
  • 18. Component Baustein einer Applikation. Eine Component besteht aus Metainformationen, einem Template und einer Klasse. Eine Applikation setzt sich aus einem Baum von Komponenten zusammen.
  • 19. Service Services dienen zur Datenhaltung und zur Kapselung von Logik.
  • 20. Directive Directives wirken sich auf das Verhalten und die Struktur des DOM aus. Sie kommen in den Templates einer Applikation vor. Eine Component ist eine Sonderform der Directive, da sie ein eigenes Template aufweist.
  • 21. Pipe Mit einer Pipe lässt sich eine gegebene Eingabe nach bestimmten Regeln in einen Ausgabe transformieren. Sie dienen vor allem der Anpassung von Anzeigewerten.
  • 22. Module C. Nöhren / pixelio.de
  • 23. Module Das App-Modul ist der Einstiegspunkt in die Applikation. Es gibt an, welche weiteren Module importiert werden, welche Components und Services verfügbar sind und welche Component die Wurzel der Applikation bildet. Das App Module wird initial vom CLI erzeugt
  • 24. Module import { … } from ‘…’; @NgModule({ declarations: […], imports: […], providers: […], bootstrap: [AppComponent] }) export class AppModule { } • declarations: Registrierung 
 von Components • imports: Importieren von 
 Modulen • providers: Registrierung von 
 Services • bootstrap: Root Component
  • 25. Component Verena N. / pixelio.de
  • 26. Component Erzeugung: ng generate component HelloWorld Es wird ein Verzeichnis mit folgendem Inhalt erzeugt: src/app/hello-world/ ├── hello-world.component.css ├── hello-world.component.html ├── hello-world.component.spec.ts └── hello-world.component.ts Die Component wird automatisch im Module registriert
  • 27. Component import { Component } from '@angular/core'; @Component({ selector: 'app-hello-world', templateUrl: './hello-world.component.html', styleUrls: ['./hello-world.component.css'] }) export class HelloWorldComponent { constructor() { } }
  • 28. Component Der grundlegende Aufbau einer Component ist: • Imports aller benötigten Dateien • Decorator mit Metadaten der Component • Component Class Der Selector gibt den Tag-Namen an über den die Component eingebunden wird. Die Component-Klasse dient der Datenhaltung für das Template und stellt Methoden zur Verfügung.
  • 30. Styling Standardmäßig gelten die in einer Component definierten Styles nur für die Component. Diese Lösung wird durch das Umbenennen der CSS-Klassen gelöst. Über die encapsulation-Eigenschaft des Decorators können auch andere Modi verwendet werden: • Native: Der Shadow-DOM wird verwendet • Emulated: CSS Renaming (Standard) • None: Keine Kapselung, Styles gelten global
  • 32. Template Angular nutzt HTML als Template-Engine. Templates können entweder inline im Decorator einer Component definiert werden oder in einer separaten HTML-Datei, was die Empfohlene Lösung ist. Per Interpolation ({{}}) kann vom Template aus auf die Eigenschaften der Component-Klasse zugegriffen werden.
  • 33. Templates import { Component } from '@angular/core'; @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.css'] }) export class ListComponent { name: string; constructor() { this.name = 'Klaus'; } } <h1>Hello {{name}}</h1> list/list.component.ts list/list.component.html
  • 35. Event-Binding Ähnlich wie auf Eigenschaften kann auch auf Methoden der Component-Class zugegriffen werden. (click)=“handleClick()” Mit dem Event-Binding wird beim Auslösen des Events z.B. eines Klicks die verbundene Methode der Component-Class aufgerufen. Dieser Methode können Eigenschaften übergeben werden. Mit der $event-Variablen erhält die Methode eine Referenz auf das Event-Objekt.
  • 36. Event-Binding export class ListComponent { greeting = ''; greetMe(event, name) { console.log(event); this.greeting = `Hello ${name}`; } } <button (click)="greetMe($event, 'Klaus')"> greet me </button> {{greeting}} list.component.html list.component.ts
  • 38. Lifecycle Im Lebenszyklus einer Component gibt es verschiedene Phase. Für jede dieser Phasen gibt es einen Hook, für den man eine Funktion definieren kann. Vorgehensweise: • Interface implementieren • Hook-Methode umsetzen import { Component, OnInit } from '@angular/core'; @Component({…}) export class ListComponent implements OnInit { ngOnInit() { // initialization here } }
  • 39. Lifecycle Wird bei der Erzeugung ausgeführt Auf eingehende Datenänderungen reagieren Initialisierung (wird nur 1x aufgerufen) Wird bei der Change Detection aufgerufen Nachdem externer Inhalt verarbeitet wurde Reaktionsmöglichkeit auf Inhaltsprüfungen Reaktionsmöglichkeit auf Initialisierung Hook nach View und View Children Wird vor der Zerstörung aufgerufen
  • 41. Child Components Eine Angular-Applikation besteht aus einem Baum von Components. In einem Template einer Component können beliebig viele Child Components referenziert werden. Diese Art der Strukturierung erhöht die Wiederverwendbarkeit einzelner Teile der Appliktion. Außerdem wird durch definierte Schnittstellen eine lose Kopplung zwischen den einzelnen Components geschaffen.
  • 42. Child Components ng generate component list-item Component auf der Kommandozeile erzeugen Component in app.module.ts (declarations) registrieren (automatisch) Component verwenden (list.component.html) <ul> <app-list-item *ngFor="let item of items"></app-list-item> </ul>
  • 43. Child Component - Input Um Informationen in eine Child Component hinein zu reichen, wird das Angular Property Binding ([]) in Verbindung mit Input Binding (@Input) verwendet. Achtung: auf @Input folgen immer Klammern. <ul> <app-list-item *ngFor="let item of items" [item]="item"> </app-list-item> </ul> @Component({…}) export class ListItemComponent { @Input() item: Item; constructor() { } }
  • 44. Child Component - Output Die Informationen, die per Input-Binding in eine Child Component hineingegeben werden, sollten nicht by Reference verändert werden. Werden die Daten angepasst, passiert dies auf einer Kopie der Daten und die Parent Component wird per Event benachrichtigt. 1. Output Binding festlegen 2. Eventhandler erzeugen und emit-Methode aufrufen 3. In der Eltern Component auf das Event reagieren
 Der Zugriff auf die Event-Daten erfolgt über die $event- Variable
  • 45. Output - Child Component <li> {{item.title}} <a (click)="delete(item.title)">remove</a> </li> @Component({ selector: 'app-list-item', templateUrl: './list-item.component.html', styleUrls: ['./list-item.component.css'] }) export class ListItemComponent { @Output() public onDelete = new EventEmitter(); … delete(title) { this.onDelete.emit(title); } }
  • 46. Output - Parent Component <ul> <app-list-item *ngFor="let item of items" [item]="item" (onDelete)="removeItem($event)"> </app-list-item> </ul> export class ListComponent implements OnInit { … removeItem(title) { const index = this.items.findIndex( item => item.title === title ); this.items.splice(index, 1); } }
  • 47. Pipes marge simpson / pixelio.de
  • 48. Pipes Pipes werden verwendet, um Anzeigewerte zu formatieren. Pipes sind Datenstreams mit Eingabe, Ausgabe und Parametern. Mit den Parametern kann das Verhalten der Pipe beeinflusst werden. Eine Pipe wird durch das | vom Eingangswert getrennt. Die Parameter werden durch Doppelpunkte getrennt. Mehrere Pipes können miteinander verkettet werden. Sie werden ebenfalls durch das |-Zeichen voneinander getrennt. Die Ausgabe einer Pipe dient dann als Eingabe für die nachfolgende.
  • 49. Pipes export class ListComponent implements OnInit { date = Date.now(); … } <div>It's {{ date | date: 'shortTime' }}</div>
  • 50. RxJS
  • 51. RxJS Die Reactive Extensions sind eine Bibliothek, die eine Implementierung des Observer-Patterns darstellen. Damit wird asynchrone Programmierung über definierte Schnittstellen möglich. Reactive Extensions sind wesentlich flexibler als Callback-Funktionen und Promises. Reactive Extensions wurden von Microsoft entwickelt und sind für viele Sprachen wie Java, C#, C++ oder JavaScript verfügbar.
  • 53. Operatoren Operatoren sind die Werkzeugkiste von RxJS. Operatoren erfüllen verschiedene Zwecke: Sie können verwendet werden, um Observables zu erzeugen, Datenströme zu Filtern oder Fehler in der Applikation zu behandeln.
  • 54. Operatoren range(1, 10) .pipe( filter(x => x % 2 === 0) ) .subscribe(x => console.log(x));
  • 55. RxJS in Components import { Component, OnInit } from '@angular/core'; import { interval } from ‘rxjs'; import { timestamp, map } from ‘rxjs/operators’; @Component({…}) export class DateComponent implements OnInit { private timestamp: number; ngOnInit() { interval(1000) .pipe( timestamp(), map(ts => ts.timestamp) ) .subscribe(ts => { this.timestamp = ts; }); } }
  • 56. Services Niko Korte / pixelio.de
  • 57. Services Services kapseln Logik und können zur Datenverwaltung verwendet werden. Mit Services kann außerdem mit anderen Systemen kommuniziert werden. Angular gibt für Services keine Struktur vor.
  • 58. Services ng generate service user Dieser Befehl erzeugt einen Service. Dieser muss anschließend noch als Provider registriert werden. Hierfür gibt es zwei Möglichkeiten: • Am Modul: Das gesamte Modul (app.module.ts unter dem Schlüssel provider) teilt sich eine Instanz des Services • An einer bestimmten Component: Eine Instanz pro Component (Component-Datei im @Component-Decorator als provider)
  • 59. import { Injectable } from '@angular/core'; import { User } from './user'; @Injectable() export class UserService { users: Array<User> = []; constructor() { } load() { this.users.push({id: 1, name: 'Peter'}); this.users.push({id: 2, name: 'Paul'}); this.users.push({id: 3, name: 'Mary'}); } get() { return this.users; } add(user: User) { this.users.push(user); } update(user: User) { const index = this.users.findIndex(existingUser => existingUser.id === user.id); this.users[index] = user; } remove(id: number) { const index = this.users.findIndex(user => user.id === id); this.users.splice(index, 1); } }
  • 61. Dependency Injection Bevor ein Service verwendet werden kann, muss er zunächst geladen werden. Dies geschieht über die Dependency Injection von Angular. Im einfachsten Fall werden die Abhängigkeiten zu anderen Elementen der Applikation im Konstruktor einer Klasse angegeben. Angular sucht daraufhin nach einem passenden Provider und liefert entweder eine bestehende Instanz aus dem Cache aus oder erzeugt eine neue Instanz.
  • 62. Dependency Injection export class ListComponent implements OnInit { users: Array<User> = []; constructor(private userService: UserService) {} ngOnInit() { this.userService.load(); this.users = this.userService.get(); } removeUser(id) { this.userService.remove(id); this.users = this.userService.get(); } }
  • 63. HTTP Angela Parszyk / pixelio.de
  • 64. HTTP Der http Service ist ein separates Modul des Angular- Frameworks. Er dient der Kommunikation mit einem Webserver und kann per Dependency Injection sowohl von anderen Services als auch direkt in Components verwendet werden. 1. HttpClientModule in app.module.ts als imports einbinden (@angular/common/http) 2. HttpClient per Dependency Injection laden 3. Instanz verwenden.
  • 65. HTTP import { Injectable } from '@angular/core'; import { HttpClient } from ‘@angular/common/http'; import { User } from './user'; import 'rxjs/add/operator/map'; @Injectable() export class UserService { users: Array<User> = []; constructor(private http: HttpClient) {} load() { this.http.get('/user') .subscribe((users: Array<User>) => { this.users = users; }); } }
  • 66. HTTP Die Methoden des HttpService geben keine Promise, sondern ein RxJS-Observable zurück. Bei diesem Objekt handelt es sich um einen asynchronen Datenstrom auf den verschiedene Operatoren wie z.B. map angewendet werden können. Mit der subscribe-Methode können Sie eine Callback-Funktion registrieren.
  • 67. HTTP Wird bei der Entwicklung ng serve verwendet, kann die proxy-Option von Webpack eingesetzt werden, um Anfragen an den Server auf einen anderen Port umzuleiten. Damit kann ein Backend an die, sich im Entwicklungsbetrieb befindende, Applikation angeschlossen werden, ohne dass Anpassungen am Quellcode erforderlich sind.
  • 69. Reactive Store Ein Reactive Store kapselt die Datenhaltung in einer internen Datenstruktur. Der Store wird nicht direkt sondern über eine definierte API modifiziert. Meist ist der Store mit dem HTTP- Service verbunden. Der Store selbst ist als Service umgesetzt, der in Components per Dependency Injection eingebunden wird. Die API verfügt meist über Methoden für CRUD-Operationen.
  • 70. Reactive Store @Injectable() export class TodoService { todos: Observable<Todo[]> private _todos: BehaviorSubject<Todo[]>; private baseUrl: string; private dataStore: { todos: Todo[] }; constructor() { this.dataStore = { todos: [] }; this._todos = <BehaviorSubject<Todo[]>>new BehaviorSubject([]); this.todos = this._todos.asObservable(); } }
  • 71. Reactive Store Das Observable dient als readonly-Schnittstelle nach außen. Intern werden Veränderungen über das BehaviorSubject publiziert. Im internen dataStore werden die Daten vorgehalten. In das BehaviorSubject können sowohl Daten geschrieben werden als auch gelesen werden. Außerdem kann es als Observable exportiert werden.
  • 72. Reactive Store create(todo: Todo) { this.dataStore.todos.push(todo); this._todos.next(Object.assign({}, this.dataStore).todos); } Operationen auf dem Store laufen immer nach dem gleichen Schema ab: Zuerst wird der lokale DataStore modifiziert, danach die next-Methode des BehaviorSubjects mit einem Klon des DataStores aufgerufen.
  • 73. Forms Bernd Kasper / pixelio.de
  • 74. Forms Angular verfügt über zwei Arten von Formularen: Template Driven Forms und Reactive Forms. Template Driven Forms sind einfacher und basieren hauptsächlich auf Templates. Reactive Forms sind flexibler und erfordern mehr TypeScript-Quellcode.
  • 75. Template Driven Forms 1. Form Modul einbinden 2. Component erstellen 3. Template erzeugen 4. Formular-Elemente mit ngModel anbinden 5. name-Attribute einfügen 6. Validierung umsetzen 7. Formular abschicken
  • 76. Template Driven Forms Das Forms Modul stellt Direktiven wie ngModel und ngForm zur Verfügung, die zur Erzeugung von Formularen erforderlich sind.
  • 77. Template Driven Forms <label for="name">Name</label> <input type="text" class="form-control" id="name" required [(ngModel)]="model.name" name="name"> Das id-Attribut wird zur Verknüpfung mit dem label verwendet. Das name-Attribut und die ngModel-Direktive dienen der Formularbehandlung durch Angular. Das required-Attribut ist eine Direktive, die einen Validator aktiviert. Durch ngModel werden die Werte direkt mit dem Model der Component synchronisiert.
  • 78. Template Driven Forms State Wahr falsch Element wurde besucht ng-touched ng-untouched Wert hat sich geändert ng-dirty ng-pristine Wert ist gültig ng-valid ng-invalid Auf den Status eines Form-Elements kann zugegriffen werden. Angular trackt verschiedene States als CSS-Klassen. Damit können Styles angewendet werden.
  • 79. Template Driven Forms <div [hidden]="name.valid || name.pristine" class=“error-message“> Name is required </div> Über den Namen des Eingabefeldes kann auch auf dessen Status zugegriffen werden und so z.B. Fehlermeldungen ein- beziehungsweise ausgeblendet werden.
  • 80. Template Driven Forms Das Formular kann mit der ngSubmit-Direktive abgesendet werden. Diese wird direkt an das Formular gebunden. Sobald das Formular über den Submit-Button abgesendet wird, wird die onSubmit-Methode der Component aufgerufen. Durch das disabled-Attribut wird der Submit-Button erst verfügbar, sobald das Formular valide ist. <form (ngSubmit)="onSubmit()" #addressForm="ngForm"> … <button type="submit" class="btn btn-success" [disabled]="! addressForm.form.valid">Submit</button> </form>
  • 81. Reactive Forms Damit Sie Reactive Forms benutzen können, müssen Sie in Ihrem Root-Module das ReactiveFormsModule einbinden (per Imports). Danach erzeugen Sie in Ihrem Template die Struktur. Die Verbindung zum Formular erfolgt hier über die formControlName-Direktive. Alles Weitere geschieht im Code der Component. Hier verwenden Sie den FormBuilder, um das Formular zu erzeugen.
  • 82. Reactive Forms export class FormComponent implements OnInit { form: FormGroup; constructor(fb: FormBuilder) { this.form = fb.group({ "name": ["", Validators.required], "password":["", Validators.required] }); } ngOnInit() { this.form.valueChanges .map((value) => { value.name = value.name.toUpperCase(); return value; }) .filter((value) => this.form.valid) .subscribe((value) => {…}); } }
  • 83. Reactive Forms <section class="sample-app-content"> <h1>Model-based Form Example:</h1> <form [formGroup]="form"> <p> <label>Name:</label> <input type="text" formControlName="name"> </p> <p> <label>Password:</label> <input type="password" formControlName="password"> </p> <p> <button type="submit" [disabled]="! form.valid">Submit</button> </p> </form> </section>
  • 85. Routing Routing bezeichnet die Navigation innerhalb einer Single Page Applikation über URLs. Eine Änderung der URL sorgt dabei nicht für einen Page Load, sodass der State der Applikation erhalten bleibt. Angular verfügt über ein eigenes Modul zu diesem Zweck: den Angular Router. Dieses Modul wird standardmäßig von der Angular CLI mit installiert.
  • 86. Routing Damit der Router funktionieren, müssen Sie in Ihrer index.html- Datei das Tag <base href=“/"> einfügen. Danach konfigurieren Sie Ihre Routen und registrieren diese in Ihrem Module.
  • 87. Routing import { RouterModule, Routes } from '@angular/router'; const appRoutes: Routes = [ { path: 'list', component: ListComponent }, { path: 'address/:id', component: AddressComponent } ]; @NgModule({ declarations: […], imports: [ RouterModule.forRoot(appRoutes) … ], providers: […], bootstrap: [AppComponent] }) export class AppModule { }
  • 88. Routing Sie können in Ihrer Routing-Konfiguration auch eine Standardroute für den Einstieg in Ihre Applikation definieren. { path: '', redirectTo: '/list', pathMatch: 'full' }
  • 89. Routing Je nachdem welche Route Sie in Ihrer Applikation aktivieren, wird ein anderer Component-Baum angezeigt. Mit dem RouterOutlet geben Sie an, wo diese Components angezeigt werden sollen. <router-outlet></router-outlet>
  • 90. Routing Innerhalb Ihrer Applikation können Sie entweder über RouterLinks oder aus dem Quellcode Ihrer Components heraus navigieren. <a routerLink="/list" routerLinkActive="active">Liste</a> routerLinkActive hilft die aktive Route visuell zu kennzeichnen. export class ListComponent { constructor(private router: Router) { } onShowDetails(address) { this.router.navigate(['/address', address.id]) } }
  • 91. Routing Routen können sowohl statische als auch dynamische Teile beinhalten. Auf diese dynamischen Inhalte können Sie über ein Observable (route.params) zugreifen. export class AddressComponent implements OnInit { constructor( private route: ActivatedRoute, private service: AddressService ) {} ngOnInit() { this.route.params .switchMap((params: Params) => this.service.get(parseInt(params['id'])) .subscribe((add: Address) => this.add = add); } }
  • 93. KONTAKT Sebastian Springer sebastian.springer@maibornwolff.de MaibornWolff GmbH Theresienhöhe 13 80339 München @basti_springer https://github.com/sspringer82