Das Problem, das jeder Angular-Entwickler kennt
\n\nHaben Sie jemals versucht, den Inhalt eines einfachen JavaScript-Objekts mit *ngFor in einer Angular-Vorlage auszugeben und plötzlich festgestellt: "Wie bekomme ich sowohl den Schlüssel als auch den Wert?" Denn *ngFor funktioniert standardmäßig nur mit Arrays. Ein Objekt ist jedoch kein Array.
Diese Frage ist eine der beliebtesten auf Stack Overflow (tausende Aufrufe und Dutzende Antworten). Entwickler suchen nicht nur nach einer Lösung, sondern nach der richtigen Lösung – einer, die die Leistung der Anwendung nicht beeinträchtigt, insbesondere wenn das Objekt groß ist oder häufig aktualisiert wird.
\n\nIn diesem Artikel geben wir nicht nur eine Antwort. Wir analysieren alle wichtigen Ansätze, von einfach bis fortgeschritten, und zeigen, wie man Code schreibt, der schnell und stabil läuft. Los geht's!
\n\nWarum funktioniert *ngFor nicht "von Haus aus" mit Objekten?
\n\nDie Direktive *ngFor in Angular ist für iterierbare Strukturen (Iterable) gedacht. Ein Array ist eine iterierbare Struktur. Ein Objekt nicht. Wenn Sie schreiben:
<div *ngFor="let item of myObject">{{ item }}</div>\n\ngibt Angular einen Fehler aus: "Cannot find a differ supporting object '...'". Angular weiß einfach nicht, wie man ein Objekt durchläuft.
\n\nIn der Praxis müssen wir jedoch oft Daten aus einem Objekt ausgeben: Konfigurationen, Wörterbücher, API-Antworten, bei denen die Schlüssel eine Bedeutung haben (z. B. { name: 'Anna', age: 25, city: 'Moskau' }).
Der einfachste Weg: Object.keys() und Object.entries()
\n\nDie beliebteste und offensichtlichste Antwort auf Stack Overflow ist, das Objekt direkt in der Vorlage oder in der Komponente in ein Array umzuwandeln.
\n\nVariante 1: Object.keys() – nur Schlüssel erhalten
\n\n// In der Komponente (TypeScript)\nexport class MyComponent {\n myObject = { name: 'Anna', age: 25, city: 'Moskau' };\n}\n\n<!-- In der Vorlage -->\n<div *ngFor="let key of objectKeys(myObject)">\n Schlüssel: {{ key }}, Wert: {{ myObject[key] }}\n</div>\n\nHier gibt es jedoch eine Einschränkung: objectKeys muss in der Vorlage verfügbar sein. Entweder machen wir es zu einer Methode der Komponente oder lagern es in eine separate Eigenschaft aus:
// Komponente\nexport class MyComponent {\n myObject = { name: 'Anna', age: 25, city: 'Moskau' };\n objectKeys = Object.keys; // einfacher Verweis auf die native Funktion\n}\n\nDas funktioniert, ruft aber bei jeder Änderungsprüfung (change detection) die Funktion auf. Wenn das Objekt groß ist, ist das ein Leistungseinbruch.
\n\nVariante 2: Object.entries() – Schlüssel und Werte auf einmal
\n\n// Komponente\nexport class MyComponent {\n myObject = { name: 'Anna', age: 25, city: 'Moskau' };\n get entries() {\n return Object.entries(this.myObject);\n }\n}\n\n<!-- Vorlage -->\n<div *ngFor="let entry of entries">\n Schlüssel: {{ entry[0] }}, Wert: {{ entry[1] }}\n</div>\n\nOder mit Destrukturierung (lesbarer):
\n\n<div *ngFor="let [key, value] of entries">\n Schlüssel: {{ key }}, Wert: {{ value }}\n</div>\n\nVorteile: einfach, verständlich, übersichtlich.
\nNachteile: Die Methode entries wird bei jedem Änderungserkennungszyklus aufgerufen. Für statische Objekte in Ordnung, für dynamische kann es problematisch werden.
Leistung: Warum ist das wichtig?
\n\nStellen Sie sich vor, Ihr Objekt enthält 10.000 Einträge. Oder es wird alle 100 ms aktualisiert (z. B. Echtzeitdaten vom Server). Jeder Aufruf von Object.entries() erzeugt ein neues Array. Angular sieht bei jedem Änderungserkennungszyklus ein "neues" Array und zeichnet die gesamte Liste neu. Dies führt zu Rucklern in der Benutzeroberfläche, Fokusverlust in Eingabefeldern und Verlangsamungen.
Daher sollte man für ernsthafte Projekte eine Optimierung verwenden.