Skip to content

Commit

Permalink
add missing published at attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
tidusIO committed Jun 25, 2024
1 parent fa02fa6 commit e248154
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ title: "Signal Inputs: Jetzt wird die Kommunikation zwischen Eltern- und Kindele
description: "Signal Inputs in Angular: Eine innovative Methode, die die Kommunikation zwischen Parent- und Child-Komponenten vereinfacht und durch einen deklarativen, reaktiven Ansatz die Developer Experience verbessert."
author: "Lulëzim Ukaj"
co_author: "David Müllerchen"
published_at:
header_source:
published_at: 2024-05-02 09:27:00.000000Z
header_source:
header_image: header.jpg
categories: "angular signals input output"
---
Expand All @@ -26,10 +26,10 @@ class="lazy img-fluid img-rounded" data-src="2.jpg" data-srcset="2.jpg"
</p>


Der [@Input()-Dekorator](https://angular.dev/guide/components/inputs#customizing-inputs) ist eines der meistgenutzten Features in Angular. Er ermöglicht es, Daten von einer Eltern- an ihre Kinderkomponente zu übertragen. Das ist einer der technischen Grundbausteine für wiederverwendbare und modulare UI-Komponenten und damit für skalierbare Web-Anwendungen in Angular. Traditionell gab es immer einiges manuell einzustellen und zu managen, wenn es darum ging, ein performantes State Management zu implementieren. Das ist zeitintensiv und erfordert auch tiefgreifende Kenntnisse der Web-Entwickler*innen.
Der [@Input()-Dekorator](https://angular.dev/guide/components/inputs#customizing-inputs) ist eines der meistgenutzten Features in Angular. Er ermöglicht es, Daten von einer Eltern- an ihre Kinderkomponente zu übertragen. Das ist einer der technischen Grundbausteine für wiederverwendbare und modulare UI-Komponenten und damit für skalierbare Web-Anwendungen in Angular. Traditionell gab es immer einiges manuell einzustellen und zu managen, wenn es darum ging, ein performantes State Management zu implementieren. Das ist zeitintensiv und erfordert auch tiefgreifende Kenntnisse der Web-Entwickler*innen.


Um das Ganze verständlicher zu machen, betrachten wir ein einfaches Beispiel:
Um das Ganze verständlicher zu machen, betrachten wir ein einfaches Beispiel:

<p class="left">
<img
Expand Down Expand Up @@ -107,15 +107,15 @@ export class CongratsChildComponent {

generateMessage(employee: string, reason: string): string {
switch(reason) {
case 'birthday':
case 'birthday':
return `Herzlichen Glückwunsch zum Geburtstag, ${employee}!`;
case 'death':
case 'death':
return `Unser tiefstes Beileid zum Verlust, betreffend ${employee}.`;
case 'birth':
case 'birth':
return `Herzlichen Glückwunsch zur Geburt, ${employee}!`;
case 'vacation':
case 'vacation':
return `Schönen Urlaub, ${employee}!`;
default:
default:
return 'Bitte wählen Sie einen Mitarbeiter und einen Grund aus.';
}
}
Expand All @@ -126,7 +126,7 @@ export class CongratsChildComponent {
## Wie machen Signal Inputs das Ganze leichter?


Die neuen Signal Inputs in Angular machen es für Entwickler um einiges leichter, mit dynamischen Komponenten zu arbeiten.
Die neuen Signal Inputs in Angular machen es für Entwickler um einiges leichter, mit dynamischen Komponenten zu arbeiten.

Anstatt wie in unserem Codebeispiel den @Input()-Dekorator und einen OnChanges-Lifecycle-Hook zu verwenden, bieten Signal Inputs eine direkte und reaktive Alternative.

Expand Down Expand Up @@ -242,12 +242,12 @@ Anstatt auf Änderungen manuell mit ngOnChanges zu reagieren, geben die Signal I
## Optionale vs. erforderliche Inputs
Angular unterscheidet klar zwischen optionalen und erforderlichen Signal Inputs.
### Optionale Inputs
Optionale Signal Inputs müssen nicht verwendet werden und können undefined sein.
Das ist für Szenarien gedacht, in denen Daten nicht an die Elternkomponente übergeben werden müssen. Beispielsweise hat das Input einen Default-Wert, der noch überschrieben werden kann. Das geschieht dann mit Hilfe der input()-Funktion.
Optionale Signal Inputs müssen nicht verwendet werden und können undefined sein.
Das ist für Szenarien gedacht, in denen Daten nicht an die Elternkomponente übergeben werden müssen. Beispielsweise hat das Input einen Default-Wert, der noch überschrieben werden kann. Das geschieht dann mit Hilfe der input()-Funktion.

**Außerdem wichtig:**
**Außerdem wichtig:**

Wenn kein Wert angegeben wird, verwendet Angular per Default “undefined” als Wert.
Wenn kein Wert angegeben wird, verwendet Angular per Default “undefined” als Wert.


Zurück zu unserem Beispiel: Angenommen, die Auswahl eines Mitarbeiters ist optional. Bei bestimmten Anlässen, wie bei einem Todesfall, soll der Name handschriftlich notiert werden:
Expand All @@ -261,7 +261,7 @@ class CongratsChildComponent {


### Erforderliche Inputs
Erforderliche Signal Inputs hingegen müssen genutzt werden. Diese Inputs werden mit der input.required()-Funktion deklariert. Hier sollen vor allem Fehler durch fehlende Daten vermieden werden.
Erforderliche Signal Inputs hingegen müssen genutzt werden. Diese Inputs werden mit der input.required()-Funktion deklariert. Hier sollen vor allem Fehler durch fehlende Daten vermieden werden.


In unserem Beispiel muss der Anlass für unsere Glückwunschkarte immer angegeben werden:
Expand All @@ -275,7 +275,7 @@ class CongratsChildComponent {


## Aliasing von Inputs
Aliasing ermöglicht es dir, ein Input in der Parent-Komponente einen anderen Namen zu geben als in der Child-Komponente. Das hat den Vorteil, dass du die Namen verwenden kannst, die am besten zum internen Kontext oder zur Logik deiner Komponenten passen. In unserem Beispiel möchtest du den selectedEmployee-Input in der Child-Komponente als employeeName nutzen. Das kannst du über die Alias-Funktion der input()-Methode erreichen.
Aliasing ermöglicht es dir, ein Input in der Parent-Komponente einen anderen Namen zu geben als in der Child-Komponente. Das hat den Vorteil, dass du die Namen verwenden kannst, die am besten zum internen Kontext oder zur Logik deiner Komponenten passen. In unserem Beispiel möchtest du den selectedEmployee-Input in der Child-Komponente als employeeName nutzen. Das kannst du über die Alias-Funktion der input()-Methode erreichen.

Betrachten wir wieder unser Grußkarten-Beispiel:

Expand All @@ -296,7 +296,7 @@ generateMessage() {
```


Das Aliasing kann in bestimmten Fällen sinnvoll sein, um zum Beispiel Namenskonflikte zu vermeiden oder für Refactoring-Arbeiten.
Das Aliasing kann in bestimmten Fällen sinnvoll sein, um zum Beispiel Namenskonflikte zu vermeiden oder für Refactoring-Arbeiten.

**ABER!**

Expand All @@ -309,7 +309,7 @@ Generell gilt, bei Aliases für @input - und @ output - Dekoratoren vorsichtig z


## Ableiten von Werten (Deriving)
Das Ableiten von Werten (Deriving) mit Signal Inputs ermöglicht es, abgeleitete States oder Werte dynamisch zu erzeugen. Mit Hilfe der computed-Funktion lassen sich leicht neue, abgeleitete States erzeugen, ohne dass sie manuell eingestellt werden müssen.
Das Ableiten von Werten (Deriving) mit Signal Inputs ermöglicht es, abgeleitete States oder Werte dynamisch zu erzeugen. Mit Hilfe der computed-Funktion lassen sich leicht neue, abgeleitete States erzeugen, ohne dass sie manuell eingestellt werden müssen.

In unserem fiktiven Beispiel könnten wir die computed-Funktion nutzen, um anhand des Mitarbeitergeschlechts unsere Glückwunschnachricht entsprechend abzuleiten. Je nachdem, ob der Name mit einem "a" endet (weiblich), soll die Grußbotschaft ein "liebe" oder "lieber" vor dem Text setzen:

Expand Down Expand Up @@ -367,10 +367,10 @@ birthDate = input('', {

## Fazit und Ausblick auf Signal Inputs

Signal Inputs in Angular bieten ein neues Tool fürs Data Binding und State Management in komplexen Webanwendungen. Der große Vorteil der neuen Inputs liegt in ihrer reaktiven Natur. Anders als traditionelle @Input-Dekoratoren ermöglichen Signal Inputs eine automatische Change Detection. Das vereinfacht die Implementierung von dynamischen Benutzeroberflächen. Das wiederum spart Zeit und Ressourcen.
Signal Inputs in Angular bieten ein neues Tool fürs Data Binding und State Management in komplexen Webanwendungen. Der große Vorteil der neuen Inputs liegt in ihrer reaktiven Natur. Anders als traditionelle @Input-Dekoratoren ermöglichen Signal Inputs eine automatische Change Detection. Das vereinfacht die Implementierung von dynamischen Benutzeroberflächen. Das wiederum spart Zeit und Ressourcen.


Die Signal sind Input sind ein weiterer Beweis, welchen Stellenwert die Developer Experience für das Angular Team dieses Jahr bekommen hat. Wir haben hier bereits oft davon gesprochen, eine verbesserte Developer Experience ist eines der Hauptziele dieses Jahr. Viele der neuen Angular Features müssen unter diesem Aspekt betrachtet werden. Während die Anforderungen an und die Komplexität der Webanwendungen gerade eher exponentiell zu steigen scheinen, reduzieren Signal Inputs den Boilerplate-Code. Das ist frischer Wind und macht Spaß.
Die Signal sind Input sind ein weiterer Beweis, welchen Stellenwert die Developer Experience für das Angular Team dieses Jahr bekommen hat. Wir haben hier bereits oft davon gesprochen, eine verbesserte Developer Experience ist eines der Hauptziele dieses Jahr. Viele der neuen Angular Features müssen unter diesem Aspekt betrachtet werden. Während die Anforderungen an und die Komplexität der Webanwendungen gerade eher exponentiell zu steigen scheinen, reduzieren Signal Inputs den Boilerplate-Code. Das ist frischer Wind und macht Spaß.
Keep the Flow, Angular!


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Open Community: Angular - Performance zwischen dynamisch gerenderten Komponenten per Template oder @switch"
description: "Marvin Heilemann zeigt uns Methoden zur Optimierung der Render-Performance von dynamischen Komponenten in Angular durch fortschrittliche Control-Flow-Syntax und effektives Refactoring"
author: "Marvin Heilemann"
published_at:
header_source:
published_at: 2024-06-18 09:27:00.000000Z
header_source:
header_image: header.jpg
categories: "angular rendering control-flow refactoring"
---
Expand All @@ -19,7 +19,7 @@ Das Formular-Modul bekommt aktuell eine JSON-Konfiguration, entweder vom Backend
- **Der Feldtyp-Komponente**: rendert ein Eingabefelder basierend auf einer Typ-Property aus der Konfiguration


Da Angular vor kurzem die Control-Flow Syntax herausgebracht hat, wollte ich diese auch hier nutzen. Aktuell rendert die Feld-Typ-Komponente die Eingabefelder per `ViewContainerRef.createComponent`. Die Komponenten liegen mit dem Typen in einem Objekt. Per `ViewChild` wird dann auf ein `ng-template` zugegriffen und anschließend das Eingabefeld dort hinein generiert.
Da Angular vor kurzem die Control-Flow Syntax herausgebracht hat, wollte ich diese auch hier nutzen. Aktuell rendert die Feld-Typ-Komponente die Eingabefelder per `ViewContainerRef.createComponent`. Die Komponenten liegen mit dem Typen in einem Objekt. Per `ViewChild` wird dann auf ein `ng-template` zugegriffen und anschließend das Eingabefeld dort hinein generiert.

Das sieht in etwa so aus:

Expand All @@ -33,7 +33,7 @@ class TypeComponent {
private readonly view!: ViewContainerRef;
@Input({ required: true }) field!: FormFieldType;
ngAfterViewInit(): void {
this.view.clear();
this.view.createComponent(formFields[this.field.type]);
Expand All @@ -45,7 +45,7 @@ class TypeComponent {
Nun, dieser Code-Teil ist bereits drei Jahre alt und ich wusste nicht, ob das hier noch eine moderne Lösung ist oder dem typischen Angular-Paradigma entspricht. Also wollte ich einen Vergleich haben zu einer anderen Methodik mit der neuen Control-Flow-Syntax: `@switch {}`. Dieser war vergleichsweise damals weitaus langsamer und komplexer zu bauen mit Typisierung.


Da sich in Angular in den letzten Jahren viel getan hat, dachte ich, dass es doch sein kann, dass andere Methoden nun viel bessere Performance erzielen. Nun bin ich aber nicht sehr tief in der Materie zu Change Detection und Rendering in Angular an sich bewandert.
Da sich in Angular in den letzten Jahren viel getan hat, dachte ich, dass es doch sein kann, dass andere Methoden nun viel bessere Performance erzielen. Nun bin ich aber nicht sehr tief in der Materie zu Change Detection und Rendering in Angular an sich bewandert.

Deshalb startete ich einen neuen Post in der mit im deutschen Raum bekanntesten Angular Community [Angular.de](www.angular.de). Hier habe ich mir, zusammen mit David Müllerchen aka Webdave, Gedanken darüber gemacht, was die richtige Herangehensweise wäre und wie die Performance in Angular am besten verglichen werden kann.

Expand All @@ -67,11 +67,11 @@ Da all meine Komponenten bekannt sind, war seine Antwort dann `@switch`. Da wir
## Performance in Angular Vergleichen


Auf dem Gebiet bin ich quasi neu, ich wusste zwar, dass es eine Angular-Erweiterung für Chromium-Browser gibt, nur hab ich sie noch nie genutzt.
Auf dem Gebiet bin ich quasi neu, ich wusste zwar, dass es eine Angular-Erweiterung für Chromium-Browser gibt, nur hab ich sie noch nie genutzt.

Also war das der Anfang. Erweiterung installiert, App aufgemacht, “Profiler” geöffnet und gestartet.
Also war das der Anfang. Erweiterung installiert, App aufgemacht, “Profiler” geöffnet und gestartet.

[Mehr zum Profiler der Angular Devtools erfährst du hier](https://angular.dev/tools/devtools#profile-your-application).
[Mehr zum Profiler der Angular Devtools erfährst du hier](https://angular.dev/tools/devtools#profile-your-application).

Nach einigen Tests kam ich damit ganz gut klar. Wichtig war mir hier, dass ich die FPS sehen kann, wie lange Komponenten laden bis sie gerendert sind und wie sich die Werte verändern beim Ein- und Ausblenden (re-render) bzw. beim Hinzufügen von neuen Elementen oder entfernen.

Expand All @@ -96,7 +96,7 @@ component.setInput("options", this.options());
Nachdem mein Use-Case nachgebaut war, baute ich noch etwas Style drum herum (ich habs gerne etwas Stylisch), ein paar Buttons zum ein- und ausblenden, zu generieren weitere Eingabefelder und Szenario-Beispiele zu generieren. In meinem Repl sind diese aber nur Text mit Signals, um es nicht zu Komplex zu gestalten.


<aside>
<aside>
🔥 Ein großes Plus, das Repl ist Zoneless (unsere App inzwischen auch) und nutzt ChangeDetection.OnPush.
</aside>

Expand All @@ -110,7 +110,7 @@ Ich habe Anfangs mit 200 Elementen für beide Möglichkeiten gestartet. Hier bin
Abweichungen können entstehen, je nachdem in welchem Browser getestet oder Gerät ein Szenario gestartet wird.


<aside>
<aside>
ℹ️ Den StackBlitz Browser, welcher als Splitview gestartet wird, kann auch als neues Tab geöffnet werden, was ein realeres Szenario darstellt, da es nicht als iFrame in StackBlitz geöffnet ist.
</aside>

Expand Down
4 changes: 2 additions & 2 deletions _posts/2024-06-18-open-community/2024-06-18-open-community.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Open Community: Veröffentliche deinen Artikel für Angular.de!"
description: "Entdecke 'Open Community' auf Angular.de – die neue Artikelserie für die Community aus der Community. Teile deinen Use Case, innovative Lösungen und Perspektiven aus aller Welt. Profitiere vom kollektiven Wissen und der Unterstützung erfahrener Entwickler"
author: "Lulëzim Ukaj"
published_at:
header_source:
published_at: 2024-06-18 09:27:00.000000Z
header_source:
header_image: header.jpg
categories: "angular open-community"
---
Expand Down

0 comments on commit e248154

Please sign in to comment.