HOWTO · Angular
getElementById-Ersetzung in Angular
Finden Sie Komponentenelemente und lesen Sie Eingabewerte in Angular mit Template-Referenzen, ElementRef und Renderer2.
Auf dieser Seite
Um ein Element zu finden, das zu einer Angular-Komponente gehört, geben Sie ihm eine Template-Referenz und fragen Sie diese Referenz mit @ViewChild ab. Dadurch bleibt die Suche auf die Komponente beschränkt, statt das gesamte Dokument nach der ID zu durchsuchen. Verwenden Sie ElementRef, wenn der Komponentencode eine Referenz auf ein natives Element benötigt, und Renderer2 für unterstützte DOM-Operationen wie das Setzen eines Styles. Diese APIs haben unterschiedliche Aufgaben; keine von beiden ist ein universeller Eins-zu-eins-Ersatz für getElementById.
getElementById-Ersetzung in Angular
Das document.getElementById("name") des Browsers durchsucht das Dokument nach einem Element, dessen id name lautet. In einer Angular-Komponente ist eine Template-Referenz in der Regel besser geeignet, wenn das Ziel Teil des eigenen Templates der Komponente ist. Fügen Sie zum Beispiel #nameInput zu einem Eingabefeld im Komponenten-Template hinzu und fragen Sie dann nameInput in der Komponentenklasse mit @ViewChild ab. Die Referenz verbindet beides, ohne dass eine dokumentweite Suche oder eine global eindeutige ID erforderlich ist.
Dieses Muster ist nützlich, wenn die Komponente nach einem Ereignis ein bestimmtes Steuerelement lesen oder aktualisieren muss. Wenn das Ziel darin besteht, einen Wert zwischen Ansicht und Komponente zu übergeben, sind Angular-Template-Bindings möglicherweise die bessere Wahl als der direkte DOM-Zugriff. Greifen Sie nur dann auf eine native Elementreferenz zurück, wenn die Aufgabe tatsächlich das Element selbst benötigt, und belassen Sie die Suche innerhalb der Komponente, der das Template gehört.
ElementRef in Angular
ElementRef ist ein Wrapper um eine native Elementreferenz. Seine Eigenschaft nativeElement legt das zugrunde liegende Element offen; er fügt diesem Element keine Angular-spezifischen Methoden hinzu. Markieren Sie das Eingabefeld im Komponenten-Template mit #nameInput; fragen Sie in der Komponentenklasse genau diesen Namen mit @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>; ab. Die Template-Referenz und der Abfragename müssen übereinstimmen, und der generische Typ teilt TypeScript mit, dass das native Element ein Eingabefeld ist.
Als konkrete Paarung kann das Template <input #nameInput type="text" value="Ada"> enthalten. Die entsprechende Klasse deklariert @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>; und kann den Wert in einem Handler mit getValue(): string { return this.nameInput.nativeElement.value; } lesen. Angular löst die Abfrage für die Komponente auf; rufen Sie den Handler von einem Ereignis aus auf, nachdem die Ansicht gerendert wurde, statt anzunehmen, dass die Referenz bereits während der Konstruktion bereit ist.
Der direkte Zugriff über nativeElement bindet den Code an das native DOM der Plattform. Das ist für eine eng begrenzte Aufgabe wie das Lesen einer Eingabeeigenschaft angemessen, aber vermeiden Sie es, ihn als allgemeinen Ersatz für Angular-Bindings zu verwenden. Es bedeutet auch, dass der Code nicht annehmen sollte, dass in Umgebungen wie dem Server-Rendering ein Browser-DOM existiert. Hier wird kein Angular-Versionsbereich behauptet; prüfen Sie die Abfragesyntax und Lebenszyklusdetails anhand der Version, die Ihre Anwendung verwendet.
Wert aus dem Eingabefeld mit ElementRef in Angular abrufen
Um das Eingabefeld zu lesen und zurückzusetzen, halten Sie die Template- und Klassenteile zusammen. Das Template kann <input #nameInput type="text" value="Ada"><button (click)="showValue()">Read</button><button (click)="resetValue()">Reset</button> lauten. Verwenden Sie in der Komponentenklasse @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>; und definieren Sie dann showValue(): void { console.log(this.nameInput.nativeElement.value); } und resetValue(): void { this.nameInput.nativeElement.value = ""; }. Die Markierung #nameInput ist die Referenz auf der Template-Seite; die an @ViewChild übergebene Zeichenkette wählt sie aus, und die Schaltflächen-Bindings rufen die Handler auf.
Dies ist ein direkter Zugriff auf das native Element: Der Wert wird aus dem Eingabeelement gelesen oder in es geschrieben. Wenn das Feld Teil eines Formulars oder des Anwendungszustands ist, ziehen Sie ein Formular-Steuerelement oder ein Binding vor, wenn das den Datenfluss besser abbildet. Diese Ansätze halten den Wert im Modell von Angular und können Validierung und Aktualisierungen leichter koordinierbar machen. Verwenden Sie ElementRef, wenn die Aufgabe ausdrücklich die Interaktion mit dem Eingabeelement verlangt, und halten Sie die Operation klein und klar.
Das folgende reine JavaScript-Beispiel modelliert nur den Zugriff auf die native Eingabeeigenschaft, den diese Handler verwenden. Es ist keine Angular-Komponente; die Paarung aus Template-Referenz und @ViewChild oben zeigt die frameworkspezifische Verdrahtung.
const input = { value: "Ada" };
const component = {
nameInput: { nativeElement: input },
getValue() {
return this.nameInput.nativeElement.value;
},
resetValue() {
this.nameInput.nativeElement.value = "";
}
};
console.log(component.getValue());
component.resetValue();
console.log(JSON.stringify(input.value));
Ada
""
Die obigen Angular-Snippets sind veranschaulichende Template- und TypeScript-Fragmente, keine eigenständig ausführbaren Beispiele. Platzieren Sie das Markup im Komponenten-Template und die Abfrage sowie die Handler in dieser Komponentenklasse; Laufzeitnachweise liegen nur für das reine JavaScript-Modell vor, daher wird keine Angular-Ausgabe behauptet.
Angular Renderer2
Renderer2 ist eine Angular-Abstraktion für unterstützte Operationen an gerenderten Elementen. Er unterscheidet sich von ElementRef: Letzteres gewährt Zugriff auf eine native Elementreferenz, während Renderer2 Methoden bereitstellt, die Operationen wie das Hinzufügen einer Klasse oder das Setzen eines Styles ausführen. Injizieren Sie ihn in die Komponente, wenn eine Operation diese Abstraktion benötigt. Er verwandelt getElementById nicht in eine Angular-Abfrage und macht willkürliche DOM-Manipulation nicht automatisch sicher.
Um Styles auf einem Element zu setzen, das der Komponente gehört, fügen Sie #styledDiv zu einem div im Template hinzu und verbinden Sie es mit einer Abfrage wie @ViewChild("styledDiv") styledDiv!: ElementRef<HTMLElement>;. Injizieren Sie Renderer2 im Konstruktor der Komponente. Rufen Sie in einem Handler applyStyles() den Befehl this.renderer.setStyle(this.styledDiv.nativeElement, "background-color", "lightblue") auf und danach erneut mit "border" und "1px solid darkblue". Eine Template-Schaltfläche kann diesen Handler mit (click)="applyStyles()" aufrufen.
Belassen Sie das Template-Markup im HTML-Template und die Abfrage, die Injektion und den Handler in der TypeScript-Klasse; beide Dateien in einen Codeblock zu packen, kann verschleiern, wo jedes Teil hingehört. Diese Aufrufe veranschaulichen Angular-APIs in ihrem Komponentenkontext und sind keine eigenständig ausführbaren Beispiele. Für gewöhnliche Darstellungsänderungen kann ein Klassen-Binding oder Style-Binding einfacher sein und hält die Bedingung im Template sichtbar. Verwenden Sie Renderer2, wenn seine Rendering-Abstraktion zur Operation passt, und vermeiden Sie zu behaupten, dass er für jede Verwendung Sicherheit oder Change-Detection-Verhalten garantiert.
Fazit: DOM-Manipulation in Angular
Beginnen Sie bei einem Element, das einer Komponente gehört, mit einer Template-Referenz und @ViewChild, statt dokumentweit mit getElementById zu suchen. Verwenden Sie ElementRef und sein nativeElement nur, wenn der Code das native Element benötigt, etwa um den Wert eines Eingabefelds zu lesen oder zurückzusetzen. Verwenden Sie Renderer2 für unterstützte Operationen wie das Setzen eines Styles. Sie ergänzen das Komponentenmodell von Angular auf unterschiedliche Weise; wählen Sie je nach Aufgabe und ziehen Sie Bindings oder Formular-Steuerelemente vor, wenn sie die gewünschte Ansicht und den Datenfluss klarer ausdrücken.