Angular. Ferdinand Malcher
Ausdruck bezieht sich immer direkt auf die zugehörige Komponentenklasse. Im einfachsten Fall ist ein solcher Ausdruck also ein Name eines Propertys aus der Klasse. Ausdrücke können aber auch komplexer sein und z. B. Arithmetik enthalten. Vor der Ausgabe werden die Ausdrücke ausgewertet, und der Rückgabewert wird schließlich im Template angezeigt. Besonders interessant ist dabei: Ändern sich die Daten im Hintergrund, wird die Anzeige stets automatisch aktualisiert! Wir müssen uns also nicht darum kümmern, die View aktuell zu halten, sondern nur die Daten in der Komponentenklasse ändern.
{{ name }} | Property der Komponente |
{{ 'foobar' }} | String-Literal |
{{ myNumber + 1 }} | Property und Arithmetik |
Die Werte null und undefined werden übrigens immer als leerer String ausgegeben.
Der Safe-Navigation-Operator ?
Stellen wir uns vor, dass wir die Felder eines Objekts in unserem Template anzeigen möchten. Wenn das Objekt allerdings undefined oder null ist, erhalten wir einen Fehler zur Laufzeit der Anwendung, weil es nicht möglich ist, auf eine Eigenschaft eines nicht vorhandenen Objekts zuzugreifen.
An dieser Stelle kann der Safe-Navigation-Operator helfen: Er überprüft, ob das angefragte Objekt vorhanden ist oder nicht. Falls nicht, wird der Ausdruck zum Binden der Daten gar nicht erst ausgewertet.
<p>{{ person?.hobbies }}</p>
Existiert das Objekt person, werden die Hobbys ausgegeben – es gibt aber keinen Fehler, wenn das Objekt undefined ist.
Operator sparsam verwenden
Aber Achtung: Bitte benutzen Sie diesen Operator sparsam. Eine bessere Praxis ist es, fehlende Objekteigenschaften mit der Strukturdirektive ngIf abzufangen (siehe Seite 84) und den kompletten Container erst dann anzuzeigen, wenn alle Daten vollständig sind. Ein weiterer Ansatz zur Lösung ist, die Propertys immer mit Standardwerten zu belegen. Hat ein Property immer einen Wert, muss auch nicht gegen undefined geprüft werden.
[Property Bindings]
Mit Property Bindings werden Daten von außen an ein DOM-Element übermittelt. Wir notieren ein Property Binding mit eckigen Klammern. Darin wird der Name des Propertys auf dem DOM-Element angegeben, das wir beschreiben wollen. Das klingt zunächst umständlich, wir werden uns aber noch ausführlich mit Property Bindings beschäftigen.
Property Bindings werden automatisch aktualisiert.
Im rechten Teil des Bindings wird ein Template-Ausdruck angegeben, also wie bei der Interpolation z. B. ein Property der aktuellen Komponente oder ein Literal. Ist das Element ein Host-Element einer Komponente, können wir die Daten innerhalb dieser Komponente auslesen und verarbeiten. Property Bindings werden ebenfalls automatisch aktualisiert, wenn sich die Daten ändern. Wir müssen uns also nicht darum kümmern, Änderungen an den Daten manuell mitzuteilen.
Das folgende Beispiel zeigt Property Bindings im praktischen Einsatz. Wir setzen damit das Property href des Anker-Elements auf den Wert der Komponenteneigenschaft myUrl. Das zweite Beispiel setzt das Property myProp der Komponente MyComponent mit dem Wert des Propertys foo aus der aktuellen Komponente.
<a [href]="myUrl">My Link</a>
<my-component [myProp]="foo">
Property Bindings werden im Abschnitt ab Seite 102 ausführlich behandelt.
Eselsbrücke
Um in JavaScript auf eine Eigenschaft eines Objekts zuzugreifen, verwenden wir ebenfalls eckige Klammern: obj[property].
(Event Bindings)
Gegenstück zu Property Bindings
Event Bindings bieten die Möglichkeit, auf Ereignisse zu reagieren, die im Template einer Komponente auftreten. Solche Ereignisse können nativ von einem DOM-Element stammen (z. B. ein Klick) oder in einer eingebundenen Komponente getriggert werden. Event Bindings sind also das Gegenstück zu Property Bindings, denn die Daten fließen aus dem Template in die Komponentenklasse. Im folgenden Beispiel wird ein click-Event ausgelöst, wenn der Nutzer den Button anklickt. Das Ereignis wird mit der Methode myClickHandler() abgefangen und behandelt.
<button (click)="myClickHandler()">Click me</button>
Wie wir Events in Komponenten auslösen und welche eingebauten Events abonniert werden können, schauen wir uns ausführlich ab Seite 114 an.
Eselsbrücke
In JavaScript verwenden wir runde Klammern für Funktionen: function(). Vor diesem Hintergrund lässt sich die Syntax für Event Bindings auch leicht merken, denn wir führen eine Funktion aus, nachdem ein Ereignis aufgetreten ist.
[(Two-Way Bindings)]
Mit Property Bindings haben wir »schreibende« und mit den Event Bindings »lesende« Operationen kennengelernt. Beide Varianten sind unidirektional, die Daten fließen also nur in eine Richtung.
Datenbindung in zwei Richtungen
Im Zusammenhang mit der Formularverarbeitung werden wir später sehen, wie wir eine Datenbindung auch in beide Richtungen aufsetzen können: von der Komponente ins Formularfeld (wenn sich die Daten ändern) und vom Formularfeld in die Komponente (wenn der Nutzer etwas eingibt). Die Syntax ist sehr einfach herzuleiten, denn es werden lediglich Property Bindings und Event Bindings miteinander kombiniert:
<input [(ngModel)]="myProperty" type="text">
Formularverarbeitung mit Two-Way Bindings schauen wir uns in Iteration IV ab Seite 275 noch ausführlich an.
Eselsbrücke
Für diese Eselsbrücke ist etwas Fantasie nötig. Die Kombination von runden und eckigen Klammern ( [()] ) sieht ein wenig wie eine Banane in einer Kiste aus (»Banana Box«). Alternativ funktioniert auch eine Eselsbrücke aus dem Ballsport: Das Runde muss ins Eckige.
#Elementreferenzen
In einem Template können wir einzelne HTML-Elemente mit Namen versehen und diese Namen an anderer Stelle verwenden, um auf das Element zuzugreifen. Damit können wir aus dem Template heraus die Eigenschaften eines Elements verwenden, ohne den Umweg über die Komponentenklasse zu gehen. Solche Elementreferenzen werden mit einem Rautensymbol # notiert.
<input #id type="text" value="Angular">
{{ id.value }}
Input-Felder haben beispielsweise immer ein Property value, in dem der aktuelle Wert hinterlegt ist. Das Beispiel {{ id.value }} macht deutlich, dass die lokale Referenz tatsächlich auf das DOM-Element zeigt und nicht nur auf dessen Wert. Beim Start wird der Text Angular neben dem Formularfeld ausgegeben. Geben wir einen neuen Wert in das Input-Feld ein, aktualisiert sich der interpolierte Text allerdings nicht. Das ist kein Fehler, sondern ein erwünschtes