angular 2: die ideen hinter datenbindung und formularen im detail betrachtet
Post on 26-Jan-2017
133 Views
Preview:
TRANSCRIPT
26.09.2016
1
Angular 2: Die Ideen hinter Datenbindung und Formularen
im Detail betrachtet
Manfred Steyer
ManfredSteyer
Über mich …
• Manfred Steyer
• SOFTWAREarchitekt.at
• Trainer & Consultant
• GDE & MVP
• Focus: Angular 2
Page 2
ManfredSteyer
26.09.2016
2
Ziele
• Wie funktioniert die Datenbindung in Angular 2?
• Wie kann man die Performance für Datenbindung verbessern?• Immutables
• Observables
Nicht-Ziele
• Allgemeine Einführung in Angular 2
26.09.2016
3
Inhalt
• Überblick zur Datenbindung in Angular 2
• Datenbindung hinter den Kulissen
• Two-Way-Binding
• Performancetuning mit Immutables und Observables
• Formulare
Warum ist dieses Thema interessant?
• Grundlegender Mechanismus jedes SPA-Frameworks
• Beeinflusst Performance maßgeblich
• Two-Way-Binding für u. a. für Biz-Anwendungen
• Ansatzpunkte für Performanceoptimierungen
26.09.2016
5
Angular-2-Anwendung sind Komponenten
Page 9
@Component({selector: 'flug-suchen',templateUrl: 'flug-suchen.html'
})export class FlugSuchenComponent {
von: string;nach: string;fluege: Array<Flug>;
constructor(http: Http) { }
search() { [...] }select(flug) { [...] }
}
Page 10
<input [(ngModel)]="von"><input [(ngModel)]="nach">
<button [disabled]="!von || !nach" (click)="search()">Search
</button>
<table><tr *ngFor="let flug of fluege">
<td>{{flug.id}}</td><td>{{flug.datum}}</td><td>{{flug.von}}</td><td>{{flug.nach}}</td>
</tr></table>
Template
26.09.2016
6
Hinter den Kulissen
Page 11
Data-Binding in AngularJS 1.x
Page 12
Model Model Directive
26.09.2016
7
Komponentne-Baum in Angular 2
Page 13
Komponente für gesamte App
Komponente (z. B. list)
Komponente
(z. B. list-item)
Komponente
(z. B. list-item)
Regeln für Property Bindings
• Komponente hängt nur von Daten des Parent ab
• Komponente hängt nie von Daten der Kinder ab
• Abhängigkeits-Graph is ein Baum
• Angular benötigt nur eine einzige Iteration („digest“) zum Abgleich des Baumes
Page 14
26.09.2016
8
Property-Binding
Page 15
model
item item
{{ item.title }} {{ item.title }}
[http://victorsavkin.com/post/110170125256/change-detection-in-angular-2]
Event-Bindings (One-Way, Bottom/Up)
Page 16
{{ item.title }} {{ item.title }}
Event-Handler
Event-Handler
26.09.2016
9
Event-Bindings (One-Way, Bottom/Up)
• Kein Digest nötig
• Event-Handler == Callbacks
• Aber: Events können Anwendungszustand verändern Digest um Property-Bindings zu aktualisieren
Page 17
Property- und Event-Bindings
Page 18
Property-Bindings
ausführen
Event-Handler warden
ausgeführt
Ereignis tritt ein
Anwendung ist bereit!
Alle Handler ausgeführt
Properties gebunden
26.09.2016
10
Bindings definieren
Page 19
View
Page 20
<button (click)="search()" [disabled]="!from || !to">Search</button>
<table>
<tr *ngFor="let flight of flights">
<td>{{flight.id}}</td>
<td>{{flight.date}}</td>
<td>{{flight.from}}</td>
<td>{{flight.to}}</td>
<td><a href="#" (click)="selectFlight(flight)">Select</a></td>
</tr>
</table>
<td [text-content]="flight.id"></td>
26.09.2016
11
Recap
• Property-Binding: One-Way; Top/Down
• Event-Binding: One-Way; Bottom/Up
• Two-Way-Binding?
• Two-Way = Property-Binding + Event-Binding
Page 21
Property- und Event-Bindings kombinieren
Page 22
<input [ngModel]="from" (ngModelChange)="updateFrom($event)">
updateFrom(newValue) {
this.from = newValue;
}
26.09.2016
12
Property- und Event-Bindings kombinieren
Page 23
<input [ngModel]="from" (ngModelChange)="from = $event">
Syntax-Zucker für Two-Way-Binding
Page 24
<input [(ngModel)]="from">
26.09.2016
13
Vorteile
• Performance
• Events: Flexibilität
• Syntaxzucker: Einfache Nutzung
Page 25
DEMO: Two-Way-Binding
Page 26
26.09.2016
14
Beispiel: flight-card
Page 27
Using flight-card
Page 28
<div *ngFor="let f of flights">
<flight-card [item]="f"
[selectedItem]="selectedFlight"
(selectedItemChange)="selectedFlight = $event">
</flight-card>
</div>
26.09.2016
15
flug-card
Page 29
flug-carditem
selectedItem
>
> > selectedItemChange
flug
selectedFlug
DEMO
26.09.2016
16
Performance-Tuning mit Immutables and Observables
Angular traversiert standardmäßig den gesamten Komponenten-Baum
flights
flight flight
{{ flight.id }} {{ flight.id }}
FlightSearch
Card Card
26.09.2016
17
Immutables
• Unveränderbare Objekte
• Wenn sich repräsentierte Daten ändern: Neues Objekt erzeugen
• Man kann einfach herausfinden, ob sich etwas geändert hat• oldObject == newObject
• Mit oder ohne Bibliotheken möglich (wie immutable.js)
Immutables
const ONE_MINUTE = 1000 * 60;
let oldFlights = this.flights;
let oldFlight = oldFlights[0]; // Flight to change!
let oldFlightDate = new Date(oldFlight.date); // Date to change
26.09.2016
18
Immutables
let newFlightDate = new Date(oldFlightDate.getTime() + ONE_MINUTE * 15);
let newFlight = {
id: oldFlight.id,
from: oldFlight.from,
to: oldFlight.to,
date: newFlightDate.toISOString()
};
let newFlights = [
newFlight,
...oldFlights.slice(1, this.flights.length)
];
this.flights = newFlights;
Auf Änderungen prüfen
console.debug("Array: " + (oldFlights == newFlights)); // false
console.debug("#0: " + (oldFlights[0] == newFlights[0])); // false
console.debug("#1: " + (oldFlights[1] == newFlights[1])); // true
26.09.2016
19
Immutables und Angular 2
• Daten fließen top/down
• Modus für Optimierung: Jedes @Input-Binding einer Komponente ist immutable
• Vereinfacht Prüfung auf Änderung
• Wenn sich kein Input einer Komponente geändert hat• Komponente inkl. aller Sub-Komponenten auslassen
Immutables und Angular
flights
flight flight
{{ flight.id }} {{ flight.id }}
FlightSearch
Card Card
Änderung
26.09.2016
20
Optimierung aktivieren
@Component({[…]changeDetection: ChangeDetectionStrategy.OnPush
})export class FlightCard {
[…]@Input flight;
}
DEMO
26.09.2016
21
Observables mit OnPush
Page 41
flights
flight$ flight$
{{ flight$.id }} {{ flight$.id }}
FlightSearch
Card Card
Change
Observables mit OnPush
Page 42
flights$
flight flight
{{ flight.id }} {{ flight.id }}
FlightSearch
Card
Change
Card
26.09.2016
22
Observable binden
<flight-card
[item]="flight | async" […]>
</flight-card>
Nicht „Alles-oder-Nichts“
• Optimierungen mit Immutables und Observables funktionieren nicht nach dem „Alles-oder-Nichts“-Prinzip
• Sie können bei Bedarf genutzt werden
26.09.2016
23
Formulare
Template-driven Forms<form>
<input type="text" name="von"
[(ngModel)]="von">
</form>
26.09.2016
24
Reaktive Formulareexport class FlugSuchenComponent {
filter: FormGroup;
constructor(flightService: FlightService, fb: FormBuilder) {
[…]
this.filter = fb.group({
von: ['Graz', Validators.required],
nach: ['Hamburg', Validators.required]
});
[…]
}
searchFlights() {
var filter = this.filter.value; […]
}
}
Reaktive Formulare
Page 48
<form [formGroup]="filter">
<input id="from" formControlName="von" type="text">
<div *ngIf="!filter.controls.von.valid">…Error…</div>
[…]
</form>
26.09.2016
25
DEMO
Fazit
• Property-Bindings: Top/Down, One-Way
• Event-Bindings: Bottom/Up, One-Way
• 2-Way-Bindings: Property-Binding + Event-Binding
• Architektur: „Fast by default“
• Wer mehr Performance benötigt: Immutables und Observables
• Template-driven Forms vs. Reactive Forms
top related