Au lieu d'injecter ElementRef
et d'utiliser querySelector
ou similaire à partir de là, un moyen déclaratif peut être utilisé à la place pour accéder directement aux éléments de la vue:
<input #myname>
@ViewChild('myname') input;
élément
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
Exemple StackBlitz
- @ViewChild () prend en charge la directive ou le type de composant comme paramètre, ou le nom (chaîne) d'une variable de modèle.
- @ViewChildren () prend également en charge une liste de noms en tant que liste séparée par des virgules (actuellement aucun espace n'est autorisé
@ViewChildren('var1,var2,var3')
).
- @ContentChild () et @ContentChildren () font de même mais dans le DOM léger (
<ng-content>
éléments projetés).
descendance
@ContentChildren()
est le seul qui permet également d'interroger les descendants
@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField;
{descendants: true}
devrait être la valeur par défaut mais n'est pas dans la version 2.0.0 finale et il est considéré comme un bug
Cela a été corrigé dans la version 2.0.1
lis
S'il existe un composant et des directives, le read
paramètre permet de spécifier quelle instance doit être retournée.
Par exemple, ce ViewContainerRef
qui est requis par les composants créés dynamiquement au lieu de la valeur par défautElementRef
@ViewChild('myname', { read: ViewContainerRef }) target;
abonner les modifications
Même si les enfants de vue ne sont définis que lorsque ngAfterViewInit()
est appelé et les enfants de contenu ne sont définis que lorsque ngAfterContentInit()
est appelé, si vous souhaitez vous abonner aux modifications du résultat de la requête, cela doit être fait dansngOnInit()
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));
}
accès direct au DOM
peut uniquement interroger des éléments DOM, mais pas des composants ou des instances de directive:
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);
}
}
obtenir un contenu projeté arbitraire
Voir Accéder au contenu transclus
input
aussi unElementRef
, mais vous obtenez la référence à l'élément que vous voulez réellement, au lieu de l'interroger à partir de l'hôteElementRef
.ElementRef
c'est très bien. L'utilisationElementRef.nativeElement
avecRenderer
est également très bien. Ce qui est déconseillé, c'est d'accéderElementRef.nativeElement.xxx
directement aux propriétés de .ElementRef.nativeElement)
, vous empêche d'utiliser le rendu côté serveur Angulars et la fonctionnalité WebWorker (je ne sais pas si cela casse également le compilateur de modèles hors ligne à venir - mais je suppose que non).@ViewChild('myObj', { read: ElementRef }) myObj: ElementRef;
Vous pouvez obtenir un handle vers l'élément DOM via
ElementRef
en l'injectant dans le constructeur de votre composant:Documents: https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
la source
ElementRef
est parti.ElementRef
est disponible (encore?).this.element.nativeElement.querySelector('#someElementId')
et passer ElementRef au constructeur comme ceci ..private element: ElementRef,
Importer la lib ...import { ElementRef } from '@angular/core';
Exemple mis à jour pour fonctionner avec la dernière version
Pour plus de détails sur l'élément natif, ici
la source
Angular 4+ : utilisation
renderer.selectRootElement
avec un sélecteur CSS pour accéder à l'élément.J'ai un formulaire qui affiche initialement une entrée e-mail. Une fois l'e-mail entré, le formulaire sera développé pour leur permettre de continuer à ajouter des informations relatives à leur projet. Cependant, s’ils ne le sont pas un client existant, le formulaire comprendra une section d'adresse au-dessus de la section d'informations sur le projet.
Pour l'instant, la partie saisie de données n'a pas été divisée en composants, les sections sont donc gérées avec les directives * ngIf. Je dois mettre l'accent sur le champ des notes du projet s'il s'agit d'un client existant ou sur le champ du prénom s'il est nouveau.
J'ai essayé les solutions sans succès. Cependant, la mise à jour 3 de cette réponse m'a donné la moitié de la solution finale. L'autre moitié provient de la réponse de MatteoNY dans ce fil. Le résultat est le suivant:
Étant donné que la seule chose que je fais est de mettre l'accent sur un élément, je n'ai pas besoin de me préoccuper de la détection des modifications, donc je peux réellement lancer l'appel à
renderer.selectRootElement
extérieur d'Angular. Étant donné que je dois donner le temps aux nouvelles sections de s'afficher, la section de l'élément est enveloppée dans un délai d'expiration pour permettre aux threads de rendu de rattraper le temps avant que la sélection de l'élément ne soit tentée. Une fois tout cela configuré, je peux simplement appeler l'élément en utilisant des sélecteurs CSS de base.Je sais que cet exemple concerne principalement l'événement focus, mais il est difficile pour moi que cela ne puisse pas être utilisé dans d'autres contextes.
la source
Pour les personnes essayant de saisir l'instance de composant dans un
*ngIf
ou*ngSwitchCase
, vous pouvez suivre cette astuce.Créez une
init
directive.Exportez votre composant sous un nom tel que
myComponent
Utilisez ce modèle pour obtenir l' instance
ElementRef
ANDMyComponent
Utilisez ce code dans TypeScript
la source
importer le
ViewChild
décorateur de@angular/core
, comme ceci:Code HTML:
Code TS:
vous pouvez maintenant utiliser l'objet 'myForm' pour accéder à n'importe quel élément qu'il contient dans la classe.
Source
la source
la source
inputTxt
dans ce cas.Remarque : Cela ne s'applique pas à Angular 6 et supérieur, comme cela
ElementRef
est devenuElementRef<T>
enT
indiquant le type denativeElement
.Je voudrais ajouter que si vous utilisez
ElementRef
, comme recommandé par toutes les réponses, vous rencontrerez immédiatement le problème quiElementRef
a une déclaration de type horrible qui ressemble àc'est stupide dans un environnement de navigateur où nativeElement est un
HTMLElement
.Pour contourner ce problème, vous pouvez utiliser la technique suivante
la source
item
doit être un , élément d' , même si vous configurez à un autre , élément d' :let item:ElementRef, item2:ElementRef; item = item2; // no can do.
. Très perturbant. Mais c'est très bien: àlet item:ElementRef, item2:ElementRef; item = item2.nativeElement
cause de l'implémentation que vous avez soulignée.let item: ElementRef, item2: ElementRef; item = item2
échoue en raison d'une analyse d'affectation définitive. Votre deuxième échoue pour les mêmes raisons, mais les deux réussissent s'ilitem2
est initialisé pour les raisons évoquées (ou en tant que vérification rapide de l'affectation que nous pouvons utiliserdeclare let
ici). Quoi qu'il en soit, vraiment dommage de voirany
sur une API publique comme celle-ci.pour obtenir le prochain frère immédiat, utilisez ceci
la source
Sélection de l'élément cible dans la liste. Il est facile de sélectionner un élément particulier dans la liste des mêmes éléments.
code composant:
Code HTML:
code CSS:
la source
Exemple minimal pour une utilisation rapide:
#inputEl
sur l'<input>
étiquette.ngAfterViewInit
crochet du cycle de vie.Remarque:
Si vous souhaitez manipuler les éléments DOM, utilisez l'API Renderer2 au lieu d'accéder directement aux éléments. Autoriser l'accès direct au DOM peut rendre votre application plus vulnérable aux attaques XSS
la source