Skip to content
Johannes Konert edited this page Mar 17, 2017 · 4 revisions

Binding und Direktiven

Ausgangslage

Als Ausgang haben wir ein relativ leeres Angular2 Projekt mit einer einzigen Komponente. https://cgmgit.beuth-hochschule.de/ng2-wf/ng2-tutorial-de/tags/0_Setup_file

Inhalt

  1. Ziel
  2. Komponentenstruktur
  3. Template Expressions
  4. Interpolation
  5. Property Binding
  6. Property Binding vs. Interpolation
  7. Event Bindings
  8. Two Way Data Binding
  9. Lifecycle Methoden

Ziel

Nach diesem Teil des Tutorials kann man:

  • Komponenten als Klassen anlegen, mit den Annotationen arbeiten
  • Variablen aus Komponenten in den Templates verwenden (1-way-Bind)
  • Variablen in Komponenten aufgrund von Benutzereingaben anpassen (2-way Bind)
  • Auf Events wie Klick/Mouseover etc. reagieren und Controller-Code ausführen
  • Den AngularJS2 Komponentenlifecycle nutzen (insbesondere OnInit bitte erklären)
  • wissen, welche Klammern und Bindings wofür, also ( ), {{}}, [] und [()],
  • was der Unterschied zwischen One-Way-Binding und Two-Way-Binding ist
  • wie man auf Events reagiert (Event Binding) ** vom Template zum Controller-Code ** AngularJS Lifecycle

Am Ende dieses Tutorials wird das Projekt so aussehen: https://cgmgit.beuth-hochschule.de/ng2-wf/ng2-tutorial-de/tags/02_Binding

Komponentenstruktur

Angular2 Komponenten sind folgendermaßen aufgebaut: Zunächst einmal importiert man andere Komponents die man braucht.

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

Dann bringt man durch die @Component Annotation Angular bei das die nun folgende Klasse eine Angular Komponente ist.

@Component({
    selector: 'my-app',
    template: '<h1>First Angular App</h1>'
})

Innerhalb dieser Annoation befinden sich die Metadaten zu der Komponente:

  • selector beschreibt an welchem HTML Selector der Component gerendert werden soll.
  • template beschreibt das zu rendernde HTML.

Danach schreiben wir die Klasse an sich:

export class AppComponent {
 //Konstruktor initalisiert die Klasse
 constructor() {
 }

app/app.component.ts

Insgesamt sieht unsere Datei nun so aus:

import { Component } from '@angular/core';
@Component({	
    selector: 'my-app',
    template: '<h1>First Angular App</h1>'
})
export class AppComponent {
  constructor() {
	}
}

Mehr Infos unter: https://angular.io/docs/ts/latest/tutorial/toh-pt1.html

Template Expressions

Template Expressions sind Javascript ähnliche Expressions die einen Wert erzeugen. Angular führt die Expression aus und ordnet sie einem Ziel zu. Dieses Ziel kann ein HTML Element, ein Component oder ein Directive sein. Nicht erlaubt in der Template Sprache sind:

  • Zuordnungen wie z.B. =, += oder -=
  • new
  • Verkettungen von Ausdrücken mit ;oder ,
  • Inkrement oder Dekrement mit ++ oder --

Mehr unter: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#template-expressions

Interpolation

Nun können wir unseren ersten One-Wy-Bind einfügen.

Durch Interpolation webt man evaluierte Strings zwischen HTML Element Tags und Attribut -Zuordnungen ein. Benutzt werden hierbei geschweifte Klammern {{}}.

Bsp. 1:

<p> My current Hero is {{currentHero.firstName}} </P>

Bsp. 2:

<img src="{{heroImageUrl}}" style="height:30px">

Bsp. 3:

<p>The sum of 1+1 is not {{1+1+getVal()}}

Zwischen den Klammern ist eine Template Expression, die Angular erst evaluiert und dann als String konvertiert.

app/app.component.ts

Wir können das also nun in unsere AppComponent einfügen. Der Bind bezieht sich dabei auf dei variable name in der Klasse.

import { Component } from '@angular/core';
@Component({	
    selector: 'my-app',
    template: '<h1>{{name}} First Angular App</h1>'
})
export class AppComponent {
	name: string;
	constructor() {
  		this.name = 'Our';
	}
}

Mehr unter: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#interpolation

Property Binding

Property Binding Bindet Template Expressions zu DOM Properties (nicht HTML Attribute) . Hierbei benutzt man eckige Klammern [ ]

Bsp. 1

<img [src] = "heroImageUrl">

app/app.component.ts

In unserem Projekt können wir nun einen Button hinzufügen, der je nachdem ob bei dem Hero die Eigenschaft noArms true oder false ist, disabled ist. Dazu erstellen wir in unserer AppComponent das neue Objekt Hero.

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    template: '<h1>{{name}} First Angular App</h1>
    <button [disabled]=hero.noArms>change weapon!</button>'
})
export class AppComponent {
  hero: Hero {
  	id: 1,
  	name: "Windstorm",
  	noArms: false,
  	weapon: "Klatsche"
  }
	name: string;
	constructor() {
  		this.name = 'Our';
	}
}

Mehr unter https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding

Property Binding vs. Interpolation

Oftmals kann man sich zwischen Property Binding und Interpolation entscheiden. Zum Beispiel machen folgende Zeilen das gleiche:

<p><img src="{{heroImageUrl}}"> is the interpolated image. </p>

<p><img [src]="heroImageUrl"> is the property bound image. </p>

In diesem Fall steht es einem frei, sich auszusuchen welche Variante man nimmt. Im Zweifel ist die Interpolation aber lesbarer.

Event Bindings

Event Bindings werden dazu benutzt um z.B. auf User Input zu reagieren. Die Syntax besteht aus dem Target-Event in Klammern links, und einem Template Statement in Anführungszeichen rechts des =Zeichens.

Bsp. 1

<button (click)="onSave()">Save</button>

Hier hören wir ob auf dem Button ein Klick ausgeführt wird und rufen dementsprechend in dem Component die Methode onSave() auf.

Bsp. 2

Template:

<input (keyup)="onKey($event)">
<p>{{values}}</vp>

Controller:

onKey(event: any) {
	this.values += event.target.value + ' | ';
}

app/app.component.ts

Jetzt können wir den Button auch mit Funktionalität versehen.

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    template: '<h1>{{name}} First Angular App</h1>
    <button [disabled]=hero.noArms (click)="weaponChange()">change weapon!</button>'
})
export class AppComponent {
  hero: Hero {
  	id: 1,
  	name: "Windstorm",
  	noArms: false,
  	weapon: "Klatsche"
  }
	name: string;
	constructor() {
  		this.name = 'Our';
	}
	weaponChange(): void {
  	this.hero.weapon = "Sword"
  }
}

Mehr unter: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#event-binding

Two Way Data Binding

Two Way Data Binding wird benutzt wenn man Daten hat die sichtbar sind, aber auch gleichzeitig vom User verändert werden können. Die Syntax [()] ist dabei eine Kombination aus Property Binding [] und Event Binding ().

Bsp. 1

<h1>{{hero.name}}</h1>
<input [(ngModel)]="hero.name">

ngModel hilft uns dabei die Syntax zu verkürzen. Allerdings müssen wir es in dem Component importieren.

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

app/app.component.ts

Durch two Way Binding ist es möglich den Namen unseres Heros in Echtzeit verändern.

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    template: '<h1>First Angular App</h1>
    <label>Name: </label> <input [(ngModel)]="hero.name">
    <button [disabled]=hero.noArms (click)="weaponChange()">change weapon!</button>'
})
export class AppComponent {
  hero: Hero {
  	id: 1,
  	name: "Windstorm",
  	noArms: false,
  	weapon: "Klatsche"
  }
	name: string;
	constructor() {
	}
	weaponChange(): void {
  	this.hero.weapon = "Sword"
  }
}

Mehr unter: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#two-way

Lifecycle Methoden

Komponenten haben Lebenszyklen, die von Angular gemanaged werden und die man über folgende Hooks erreichen kann:

  • ngOnChanges
  • ngOnInit
  • ngDoCheck
  • ngAfterContentInit
  • ngAfterContentChecked
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngOnDestroy

Im Detail:

ngOnChanges()

Wird vor ngInit() aufgerufen und wenn ein oder mehrere data-inbound Properties sich ändern. Nimmt ausserdem ein SimpleChanges Objekt entgegen welches derzeitige und frühere Properties beinhaltet.

ngOnInit()

Wird nur einmal, direkt nach ngOnChanges() aufgerufen und initialisiert Komponenten.

ngDoCheck()

Wird direkt nach ngOnChanges() und ngOnInit() ausgeführt. Falls Angular selber Änderungen nicht mitkriegen kann, kann man sie mit dieser Methode finden und darauf reagieren.

ngAfterContentInit()

Wird einmal nach ngDoCheck() ausgeführt, also direkt nachdem sich aller Content initialisiert hat.

ngAfterContentChecked()

Wird nach ngAfterContentInit() und jedem ngDoCheck() ausgeführt.

ngAfterViewInit()

Wird nachdem die Views und Childviews initialisiert sind ausgeführt und einmal nach dem ersten ngAfterContentChecked().

ngOnDestroy()

Aufräumarbeiten bevor Angular das Directive oder den Component zerstört. Hier kann man Event-Handler detachen um Memory-Leaks vorzubeugen.

app/app.component.ts

Durch two Way Binding ist es möglich den Namen unseres Heros in echtzeit verändern.

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    template: '<h1>First Angular App</h1>
    <label>Name: </label> <input [(ngModel)]="hero.name">
    <button [disabled]=hero.noArms (click)="weaponChange()">change weapon!</button>'
})
export class AppComponent {
  hero: Hero {
  	id: 1,
  	name: "Windstorm",
  	noArms: false,
  	weapon: "Klatsche"
  }
	name: string;
	ngOnInit() {
  		this.hero.noArms = false	
	}
	weaponChange(): void {
  	this.hero.weapon = "Sword"
  }
}

Mehr unter: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

Clone this wiki locally