Templates - Grundlagen

Interpolation

doppelte geschweifte Klammern: {{}}

                     
                         

{{title}}

Verschachtelt: {{customer.name}}

Funktionsaufruf: {{20 + add(2, 5)}}

{{customer.name}} customer = { id: "abc", name: "Hans Muster", }; add(a: number, b: number) { return a + b; }

Interpolation im Detail

  • nutzt Properties oder Methoden der Komponente
  • die Interpolation wird durch den Wert ersetzt
  • wie der Aufruf der add Funktion zeigt: zwischen den Klammern steht eine Template Expression
  • die Expression wird zuerst evaluiert, in einen String konvertiert und mit anderen Strings verbunden. Zuletzt wird der Wert dem Element zugewiesen.

Aufgabe 6.1 - Interpolation

  • Erzeuge eine Adresse als Objekt-Literal. Nutze Felder wie Strasse, Nr, Ort, PLZ
  • Zeige die einzelnen Felder in einer Liste an
  • Schreibe eine Funktion die die komplette Adresse rendert und stelle diese dar
  • Hint: Ungeordnete Listen sehen so aus
                     
                         
  • List Item 1

Aufgabe 6.1 - Mögliche Lösung

                     
                        address = {
                            street: 'Musterstrasse',
                            number: '42',
                            zip: '3000',
                            city: 'Bern'
                        };

                        renderAddress() {
                            return `${this.address.street} ${this.address.number},
                                ${this.address.zip} ${this.address.city}`
                        }

                        
  • {{adresse.strasse}}
  • ...

{{renderAddress()}}

Template Expressions

  • in den Interpolationsklammern befindet sich eine Template Expression, z.B. {{1 + 1}}
  • ein reduziertes Set von JavaScript
  • keine Assigmnents (=, +=, *=, ...) erlaubt
  • kein new
  • keine Seiteneffekte wie ++ (Idempotenz, pure Functions)

Template Statements

  • Ausführen von Seiteneffekten
  • reagieren auf Events (Benutzer Aktionen)
                     
                         
                     
                 

Bindings

Übersicht (1)

Richtung Syntax Name
One-way, Komponente zur View
                                 
                                     {{expression}}
                                     [property] = "expression"
                                 
                             
Property, Attribut, Style...

Übersicht (2)

Richtung Syntax Name
One-way, View zur Komponente
                                 
                                     (event) = "statement()"
                                 
                             
Event
Two-way
                                 
                                     [(property)] = "expression"
                                 
                             
Two-way

Property Binding - [property]

Beispiele

                     
                         Klick mich
                     
                    
                         
                     
                    
                         
                     
                 

Aufgabe 6.2 - Property Binding

  • Füge ein input Element hinzu
  • Binde den Wert der Strasse an das Value-Property des Input Feldes

Aufgabe 6.2 - Mögliche Lösung

                     
                         
                     
                

... oder die Canonical Form mit dem bind-Präfix

                    
                         
                     
                 

HTML und DOM

  • DOM ist nicht wirklich ein Model, sondern die Schnittstelle zum Zugriff auf HTML
  • HTML kennt Attribute (z. B. value)
  • DOM kennt Properties (z. B. value)
  • HTML value ist der initale Wert
  • DOM value ist der aktuelle Wert

Attribute vs. Properties

  • HTML Attribute initialisieren lediglich DOM Properties
  • DOM Properties können sich ändern, Attribute nicht
  • Die Bindings in Angular arbeiten ausschliesslich mit DOM Properties und Events, NICHT mit HTML Attributen

Event binding - (event)

Beispiele

                     
                         
                     
                    
                         
                     
                    
                         
                     
                 

Aufgabe 6.3 - Event Binding

  • Füge einen Button hinzu.
  • Rufe beim Klick eine Methode auf, die etwas auf der Konsole ausgibt.

Aufgabe 6.3 - Mögliche Lösung

                     
                         
                     
                     
                         logHello() {
                            console.log("Hello");
                         }
                     
                

... oder die Canonical Form mit dem on-Präfix

                     
                         
                     
                 

$event

Werte per Event übergeben

                     
                         
                         print(value) {
                            console.log(value);
                         }
                     
                

... oder den Wert in der Methode auslesen

                      
                         
                         printEvent(event) {
                            console.log(event.target.value);
                         }
                     
                 

Zugriff auf Werte

                     
                         
                     
                 
  • Events sind vom Typ KeyboardEvent, MouseEvent, FocusEvent, InputEvent... oder auch eigene Events
  • Das target property ist eine Referenz auf das Element, welches das Event ausgelöst hat
  • mit .value kann auf den Wert zugegriffen werden

Aufgabe 6.4 - Event mit Wert

  • Fuege ein Input Element hinzu.
  • Gib jeden neuen Wert, auf der Konsole aus, wenn dieser mit dem Buchstaben 's' beginnt.

Aufgabe 6.4 - Mögliche Lösung

                     
                         
                     
                     
                         printSValues(val: string) {
                            if(val.toLowerCase().startsWith("s")) {
                                console.log(val);
                            }
                         }
                     
                 

Aufgabe 6.5 - Two-way data binding

  • Erstelle ein selbst kreiertes Two-way Data Binding für ein Input Feld.
  • Erstelle ein Input Feld mit einem Binding für einen String, z. B. "name"
  • Erstelle einen Textblock "p-Tag" der den Wert aus dem Eingabefeld anzeigt.
  • Nutze ein Property-Binding, ein Event-Binding und eine Variable in der Komponente.

Aufgabe 6.5 - Mögliche Lösungen

                     
                         
                         

{{name}}

name = "Hans";

Oder mit einer Funktion in der Komponente:

                     
                         
                         

{{name}}

name = "Hans"; fun(value: string) { this.name = value;}

Two-way data binding - [()]

«banana-in-a-box | Bananenkiste»

                    
                        
  • intern nur ein Property und ein Event Binding

Two-way Binding mit NgModel

                    
                       <input [ngModel]="name"
                              (ngModelChange)="handleChange($event)">
                       <input [ngModel]="name"
                              (ngModelChange)="name=$event">

                       name: string = "Hans";
                       handleChange(newValue) {
                            this.name = newValue;
                       }
                    
                    
                        <input [(ngModel)]="name">
                    
                
  • [property]Binding mit einem (propertyChange) Event

NgModel in Detail

  • benötigt das Modul FormsModule
  • ist eine Kombination aus [ngModel] und (ngModelChange)
  • Der Wert steht direkt in der $event-Variable
  • Angular kapselt den Zugriff auf den DOM. Welches Event? Welches Property?
  • Für eigene Komponenten: ControlValueAccessor Interface implementieren

Aufgabe 6.6 - NgModel

  • Erstelle ein Two-way data binding mit ngModel für eine Textarea zum Anzeigen einer Notiz note.
  • Nutze die kurze "Bananenschachtel" Syntax.
  • Erstelle ein p-tag und gebe dort den Text der Variablen note aus.
  • Erstelle einen Button um den Text der Notiz auf "Platzhalter" zurück zu setzen.

Aufgabe 6.6 - Mögliche Lösung (1)

Benötigten Import im Module hinzufügen:

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

                         @NgModule({
                            ...
                            imports: [
                                BrowserModule,
                                FormsModule
                            ],
                            ...
                         })
                     
                

Aufgabe 6.6 - Mögliche Lösung (2)

                     
                         <textarea [(ngModel)]="note"
                                   placeholder="Notiz...">

                         

{{note}}

note = ""; resetNote() { this.note = ""; }

Template Referenz Variable - #variable

Syntax im HTML - mit #name

                     
                         <input #note>
                         
                     
                     
                         print(value) {console.log(value);}
                     
                

# - behind the scenes

  • Eine Referenz auf ein DOM Element, oder eine Komponente
  • Im gesamten Template verfügbar
  • Eine Referenz auf ein Input Element liefert das tatsächliche Element zurück, wie $event.target
  • Alternative syntax: ref-note statt #note

Aufgabe 6.7 - Template Ref Variable

  • Erstelle einen Button und eine Checkbox.
  • Die Checkbox soll den Button disablen / enablen
  • Benutze hierfür eine Template Referenz Variable
  • Hint: ein Button hat ein disabled Property
  • Hint: ein Input hat ein (change) Event

Aufgabe 6.7 - Mögliche Lösung

                     
                         <input type="checkbox"
                                (change)="btn.disabled = !btn.disabled">

                         <button #btn>Button
                     
                

Das war easy