📖4. Add Services

Mittels Services lassen sich Funktionalitäten und Businesslogik zentralisieren, dies bietet einige Vorteile:

  1. Trennung von Zuständigkeiten (Separation of Concerns): Durch die Auslagerung bestimmter Funktionalitäten in Services kann die Logik von der UI-Komponente getrennt werden.

  2. Wiederverwendbarkeit: Ein gut entwickelter Service kann in verschiedenen Teilen einer Anwendung oder sogar in verschiedenen Projekten wiederverwendet werden, ohne dass der Code kopiert oder geändert werden muss.

  3. Erhöhte Testbarkeit: Services, die von der UI oder anderen Abhängigkeiten getrennt sind, lassen sich in der Regel leichter testen.

  4. Zentralisierte Logik: Services zentralisieren die Geschäftslogik und Datenzugriffe. Dies bedeutet, dass Änderungen oder Fehlerbehebungen nur an einem Ort vorgenommen werden müssen, was die Qualität und Konsistenz des Codes verbessert. Änderungen werden dementsprechend nur an einem Ort durchgeführt.

In Angular werden Services häufig verwendet und erleichtern die Nutzung von komplexen Funktionalitäten.

Dependency Injection (DI)

Bei DI handelt es sich um ein Entwurfsmuster aus dem Bereich der Objektorientierung. Bei der Initialisierung eines Komponenten werden benötigte Abhängigkeiten festgelegt, welche bereits zur Verfügung sein müssen. Dies wird meist von Containern oder übergeordneten Komponenten geregelt.

@Injectable()

Durch den Injectable Symbol, deklarieren wir Services als DI fähig. Heisst, diese Services können im Constructor definiert und werden somit mittels DI geladen.

@Injectable({
  providedIn: 'root',
})

Zusätzlich wird angegeben, dass dieser Service auf dem Root level provided wird. Somit wird eine shared Instanz des HeroService erstellt und für zur Verfügung gestellt. Ab diesem Moment sind Komponente in der Lage im Konstruktur die Instanz des HeroServices zu referenzieren.

constructor(private heroService: HeroService) {}

Observable

Observables gehören zu den Schlüsselklassen des RxJS Bibliotheks. Die Mockdaten die wir bis anhieb nutzen konnten und die getHeroes() Methode aus dem Service werden beide synchron geladen. In einer Übung funktioniert das, aber in der Realität wird ausschliesslich nur mit asynchronen Daten gearbeitet.

Mittels Observables besteht die Möglichkeit Daten lazy zu laden und zu abonnieren, falls diese effektiv geladen werden sollen. So kann auch mittels der of() Methode synchrone Daten in Observables umgewandelt werden.

Wir sehen uns zwei verschiedene Arten an, wie wir Daten von Observables erhalten können.

  1. Laden von Observabels in der Businesslogik

In der Businesslogik können Daten aus einem Observable mittels .subscribe() Methode geladen werden.

getHeroes(): void {
  this.heroService.getHeroes()
      .subscribe(heroes => this.heroes = heroes);
}

Zu beachten ist, dass die lokale Instanz von Helden im subscribe,durch die entfernten Daten der heroes, überschrieben wird. Benötigt jederzeit eine lokale Variable, welche überschrieben werden muss.

  1. Laden von Observables im Template

Einer der gängigeren Methoden ist die Verwendung durch den Async-Pipe.

heros$: Observable<Hero[]> = this.heroService.getHeroes();

Durch das $-Zeichen wird gekennzeichnet, dass es sich um asynchrone Daten handelt. Die Methode getHeroes liefert uns Observable<Hero[]> diese weisen wir einer lokalen Variable zu. Nun können wir im Template darauf referenzieren und mittels Async-Pipe die Daten laden.

<li *ngFor="let hero of heroes$ | async">

In diesem Beispiel laden wir alle Heroes asynchron und weisen jeden einzelnen Helden darin in eine lokale Variable hero.

Last updated