Warum funktioniert document.querySelector in Angular nicht einfach?
\n\nStellen Sie sich vor: Sie schreiben Ihre erste Angular-Anwendung und müssen auf ein einfaches <div> oder <input> direkt in der Komponentenvorlage zugreifen. Der erste Gedanke ist, das gute alte document.querySelector zu verwenden. Aber leider: In der Konsole erscheint null oder undefined. Kommt Ihnen das bekannt vor?
Angular ist nicht nur eine Bibliothek zur DOM-Manipulation. Es ist ein Framework, das mit seiner eigenen Abstraktion über dem realen DOM arbeitet. Der direkte Zugriff auf Elemente über globale Selektoren verletzt die Architektur des Frameworks, kann zu Speicherlecks und Leistungsproblemen führen. Der Hauptgrund ist jedoch, dass Angular ein virtuelles DOM und Shadow DOM verwendet (abhängig von der Kapselungsstrategie), sodass Ihr document.querySelector die Elemente innerhalb der Komponente einfach nicht sieht.
Glücklicherweise haben die Angular-Entwickler eine elegante Lösung vorgesehen – die Dekorateure ViewChild und ViewChildren. In diesem Artikel werden wir untersuchen, wie man Elemente in der Komponentenvorlage mit TypeScript korrekt auswählt, und alle Fallstricke betrachten.
\n\nGrundlegende Methoden für den Zugriff auf Vorlagenelemente
\n\nIn Angular gibt es drei Hauptansätze zur Auswahl von Elementen in der Komponentenvorlage:
\n\n- \n
- Vorlagenreferenzen (Template Reference Variables) – die einfachste Methode für schnellen Zugriff \n
- Dekorateur ViewChild – für den Zugriff auf ein einzelnes Element oder eine Komponente \n
- Dekorateur ViewChildren – für den Zugriff auf eine Sammlung gleichartiger Elemente \n
Jeder dieser Ansätze hat seine eigenen Besonderheiten und wird in verschiedenen Szenarien eingesetzt. Lassen Sie uns diese genauer betrachten.
\n\n1. Vorlagenreferenzen: Der schnellste Weg
\n\nVorlagenreferenzen sind ein "Lifehack" von Angular, der es Ihnen ermöglicht, direkt in der Vorlage auf ein DOM-Element zuzugreifen, ohne Code in der Komponentenklasse schreiben zu müssen. Sie setzen einfach #referenzname auf das gewünschte Element.
// component.html\n<input #myInput type="text" placeholder="Text eingeben">\n<button (click)="focusInput(myInput)">Fokus auf Eingabefeld</button>\n\nIn diesem Beispiel ist #myInput eine Vorlagenreferenz. Sie erstellt automatisch eine Variable, die an Methoden der Komponente übergeben werden kann. Beachten Sie: Wir übergeben das Element selbst, nicht seinen Wert.
// component.ts\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'app-example',\n templateUrl: './example.component.html'\n})\nexport class ExampleComponent {\n focusInput(inputElement: HTMLInputElement): void {\n inputElement.focus();\n inputElement.style.borderColor = '#4CAF50';\n }\n}\n\nWichtiger Punkt: Vorlagenreferenzen sind nur innerhalb der Vorlage verfügbar. Sie können sie nicht direkt in der Komponentenklasse verwenden. Dafür werden Dekorateure benötigt.
\n\n2. ViewChild: Zugriff auf ein einzelnes Element
\n\nDer Dekorateur @ViewChild ist das Hauptwerkzeug, um aus der Komponentenklasse auf ein Element oder eine untergeordnete Komponente zuzugreifen. Er arbeitet auf Basis eines Selektors: Sie können nach Vorlagenreferenz, nach Komponententyp oder nach CSS-Selektor (mit Einschränkungen) suchen.
// component.ts\nimport { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';\n\n@Component({\n selector: 'app-example',\n template: `\n <div #myDiv>Dieses Element werden wir auswählen</div>\n <p #myParagraph>Und dieses auch</p>\n `\n})\nexport class ExampleComponent implements AfterViewInit {\n @ViewChild('myDiv') myDiv!: ElementRef;\n @ViewChild('myParagraph') myParagraph!: ElementRef;\n\n ngAfterViewInit(): void {\n // Wichtig! Der Zugriff auf Elemente ist erst nach der Initialisierung der Ansicht möglich\n console.log(this.myDiv.nativeElement.textContent); // "Dieses Element werden wir auswählen"\n this.myPara