Anstatt von dort aus zu injizieren ElementRef
und zu verwenden querySelector
oder ähnliches zu verwenden, kann stattdessen eine deklarative Methode verwendet werden, um direkt auf Elemente in der Ansicht zuzugreifen:
<input #myname>
@ViewChild('myname') input;
Element
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
StackBlitz Beispiel
- @ViewChild () unterstützt die Direktive oder den Komponententyp als Parameter oder den Namen (String) einer Vorlagenvariablen.
- @ViewChildren () unterstützt auch eine Liste von Namen als durch Kommas getrennte Liste (derzeit sind keine Leerzeichen zulässig
@ViewChildren('var1,var2,var3')
).
- @ContentChild () und @ContentChildren () machen dasselbe, jedoch im hellen DOM (
<ng-content>
projizierte Elemente).
Nachkommenschaft
@ContentChildren()
ist die einzige, mit der auch Nachkommen abgefragt werden können
@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField;
{descendants: true}
sollte die Standardeinstellung sein, ist aber nicht in 2.0.0 final und wird als Fehler angesehen.
Dies wurde in 2.0.1 behoben
lesen
Wenn es eine Komponente und Anweisungen gibt, kann der read
Parameter angeben, welche Instanz zurückgegeben werden soll.
Dies ist beispielsweise ViewContainerRef
für dynamisch erstellte Komponenten anstelle der Standardeinstellung erforderlichElementRef
@ViewChild('myname', { read: ViewContainerRef }) target;
Änderungen abonnieren
Obwohl Ansichtskinder nur festgelegt werden, wenn sie ngAfterViewInit()
aufgerufen werden, und Inhaltskinder nur festgelegt werden, wenn sie ngAfterContentInit()
aufgerufen werden, sollte dies in erfolgen, wenn Sie Änderungen am Abfrageergebnis abonnieren möchtenngOnInit()
https://github.com/angular/angular/issues/9689#issuecomment-229247134
@ViewChildren(SomeType) viewChildren;
@ContentChildren(SomeType) contentChildren;
ngOnInit() {
this.viewChildren.changes.subscribe(changes => console.log(changes));
this.contentChildren.changes.subscribe(changes => console.log(changes));
}
direkter DOM-Zugriff
kann nur DOM-Elemente abfragen, aber keine Komponenten oder Direktiveninstanzen:
export class MyComponent {
constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
// for transcluded content
ngAfterContentInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
}
Beliebig projizierten Inhalt erhalten
Siehe Zugriff auf ausgeschlossene Inhalte
input
ist auch einElementRef
, aber Sie erhalten den Verweis auf das Element, das Sie tatsächlich wollen, anstatt es vom Host abzufragenElementRef
.ElementRef
in Ordnung. Auch mitElementRef.nativeElement
zu verwendenRenderer
ist in Ordnung. Was davon abgeraten wird, ist derElementRef.nativeElement.xxx
direkte Zugriff auf Eigenschaften von .ElementRef.nativeElement)
ist, verhindert, dass Sie das serverseitige Rendering und die WebWorker-Funktion von Angulars verwenden (ich weiß nicht, ob dadurch auch der bevorstehende Offline-Vorlagen-Compiler beschädigt wird - aber ich denke nicht).@ViewChild('myObj', { read: ElementRef }) myObj: ElementRef;
Sie können ein Handle für das DOM-Element erhalten,
ElementRef
indem Sie es in den Konstruktor Ihrer Komponente einfügen:Dokumente: https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
quelle
ElementRef
weg ist.ElementRef
ist verfügbar (wieder?).this.element.nativeElement.querySelector('#someElementId')
und ElementRef wie folgt an den Konstruktor übergeben.private element: ElementRef,
Import lib ...import { ElementRef } from '@angular/core';
Beispiel aktualisiert, um mit der neuesten Version zu arbeiten
Weitere Details zum nativen Element finden Sie hier
quelle
Winkel 4+ : Verwenden Sie diese Option
renderer.selectRootElement
mit einem CSS-Selektor, um auf das Element zuzugreifen.Ich habe ein Formular, in dem zunächst eine E-Mail-Eingabe angezeigt wird. Nachdem die E-Mail eingegeben wurde, wird das Formular erweitert, damit sie weiterhin Informationen zu ihrem Projekt hinzufügen können. Wenn es sich jedoch nicht um einen vorhandenen Kunden handelt, enthält das Formular einen Adressabschnitt über dem Projektinformationsabschnitt.
Bis jetzt wurde der Dateneingabeabschnitt nicht in Komponenten aufgeteilt, daher werden die Abschnitte mit * ngIf-Direktiven verwaltet. Ich muss mich auf das Feld Projektnotizen konzentrieren, wenn es sich um einen vorhandenen Client handelt, oder auf das Feld Vorname, wenn es neu ist.
Ich habe die Lösungen ohne Erfolg ausprobiert. Update 3 in dieser Antwort gab mir jedoch die Hälfte der möglichen Lösung. Die andere Hälfte kam von MatteoNYs Antwort in diesem Thread. Das Ergebnis ist folgendes:
Da ich mich nur auf ein Element konzentriere, muss ich mich nicht mit der Änderungserkennung befassen, damit ich den Anruf tatsächlich
renderer.selectRootElement
außerhalb von Angular ausführen kann . Da ich den neuen Abschnitten Zeit zum Rendern geben muss, wird der Elementabschnitt in eine Zeitüberschreitung eingeschlossen, damit die Rendering-Threads Zeit zum Aufholen haben, bevor die Elementauswahl versucht wird. Sobald alles eingerichtet ist, kann ich das Element einfach mit einfachen CSS-Selektoren aufrufen.Ich weiß, dass sich dieses Beispiel hauptsächlich mit dem Fokusereignis befasst, aber es fällt mir schwer, dass dies nicht in anderen Kontexten verwendet werden kann.
quelle
Für Personen, die versuchen, die Komponenteninstanz in einem
*ngIf
oder zu erfassen*ngSwitchCase
, können Sie diesen Trick befolgen.Erstellen Sie eine
init
Direktive.Exportieren Sie Ihre Komponente mit einem Namen wie
myComponent
Verwenden Sie diese Vorlage, um die
ElementRef
AND-MyComponent
Instanz abzurufenVerwenden Sie diesen Code in TypeScript
quelle
Importieren Sie den
ViewChild
Dekorateur@angular/core
wie folgt:HTML Quelltext:
TS-Code:
Jetzt können Sie mit dem Objekt 'myForm' auf jedes Element in der Klasse zugreifen.
Source
quelle
quelle
inputTxt
in diesem Fall einen undefinierten Wert für ergeben .Hinweis : Dies gilt nicht für Angular 6 und höher als
ElementRef
wurdeElementRef<T>
mitT
der Art der angibtnativeElement
.Ich möchte hinzufügen, dass, wenn Sie
ElementRef
, wie in allen Antworten empfohlen, verwenden, Sie sofort auf das Problem stoßen,ElementRef
das eine schreckliche Typdeklaration hat, die aussiehtDies ist in einer Browser-Umgebung, in der nativeElement eine ist, dumm
HTMLElement
.Um dies zu umgehen, können Sie die folgende Technik verwenden
quelle
item
sich um ein ElementRef handeln muss, obwohl Sie es auf ein anderes ElementRef setzen :let item:ElementRef, item2:ElementRef; item = item2; // no can do.
. Sehr verwirrend. Aber das ist in Ordnung:let item:ElementRef, item2:ElementRef; item = item2.nativeElement
wegen der Implementierung, auf die Sie hingewiesen haben.let item: ElementRef, item2: ElementRef; item = item2
schlägt Ihr erstes Beispiel aufgrund einer eindeutigen Zuordnungsanalyse fehl. Ihr zweiter Fehler schlägt aus denselben Gründen fehl, aber beide sind erfolgreich, wenn eritem2
aus den genannten Gründen initialisiert wurde (oder als nützliche schnelle Überprüfung der Zuweisbarkeit, die wirdeclare let
hier verwenden können). Ungeachtet dessen ist es wirklich eine Schande,any
auf einer öffentlichen API wie dieser zu sehen.Verwenden Sie diese Option, um das nächste Geschwister zu erhalten
quelle
Zielelement aus der Liste auswählen. Es ist einfach, ein bestimmtes Element aus der Liste derselben Elemente auszuwählen.
Komponentencode:
HTML Quelltext:
CSS-Code:
quelle
Minimales Beispiel für eine schnelle Verwendung:
#inputEl
auf dem<input>
Tag.ngAfterViewInit
Lebenszyklus-Hook zu.Hinweis:
Wenn Sie die DOM-Elemente bearbeiten möchten, verwenden Sie die Renderer2-API, anstatt direkt auf die Elemente zuzugreifen. Durch das Zulassen des direkten Zugriffs auf das DOM wird Ihre Anwendung anfälliger für XSS-Angriffe
quelle