HOWTO · Angular

Remplacement de getElementById dans Angular

Trouvez des éléments de composant et lisez les valeurs des champs de saisie dans Angular avec les références de modèle, ElementRef et Renderer2.

Sur cette page

Pour trouver un élément qui appartient à un composant Angular, attribuez-lui une référence de modèle et interrogez cette référence avec @ViewChild. Cela limite la recherche au composant au lieu de parcourir tout le document par ID. Utilisez ElementRef lorsque le code du composant a besoin d’une référence à un élément natif, et utilisez Renderer2 pour les opérations DOM prises en charge, comme la définition d’un style. Ces API ont des rôles différents ; aucune n’est un remplacement universel un pour un de getElementById.

Remplacement de getElementById dans Angular

Le document.getElementById("name") du navigateur recherche dans le document un élément dont l’id est name. Dans un composant Angular, une référence de modèle convient généralement mieux lorsque la cible fait partie du propre modèle de ce composant. Par exemple, ajoutez #nameInput à un champ de saisie dans le modèle du composant, puis interrogez nameInput avec @ViewChild dans la classe du composant. La référence relie les deux sans nécessiter une recherche dans tout le document ni un ID globalement unique.

Ce motif est utile lorsque le composant doit lire ou mettre à jour un contrôle particulier après un événement. Si le but est de passer une valeur entre la vue et le composant, les liaisons de modèle Angular peuvent être un meilleur choix que l’accès direct au DOM. Ne recourez à une référence à un élément natif que lorsque la tâche a réellement besoin de l’élément lui-même, et gardez la recherche à l’intérieur du composant qui possède le modèle.

ElementRef dans Angular

ElementRef est un wrapper autour d’une référence à un élément natif. Sa propriété nativeElement expose l’élément sous-jacent ; elle n’ajoute pas de méthodes spécifiques à Angular à cet élément. Dans le modèle du composant, marquez le champ de saisie avec #nameInput ; dans la classe du composant, interrogez ce nom exact avec @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>;. La référence de modèle et le nom de la requête doivent correspondre, et le type générique indique à TypeScript que l’élément natif est un champ de saisie.

Comme appariement concret, le modèle peut contenir <input #nameInput type="text" value="Ada">. La classe correspondante déclare @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>; et peut lire la valeur dans un gestionnaire avec getValue(): string { return this.nameInput.nativeElement.value; }. Angular résout la requête pour le composant ; appelez le gestionnaire depuis un événement après le rendu de la vue, plutôt que de supposer que la référence est prête pendant la construction.

L’accès direct via nativeElement lie le code au DOM natif de la plateforme. C’est approprié pour une tâche étroite comme la lecture d’une propriété d’un champ de saisie, mais évitez de l’utiliser comme substitut général aux liaisons Angular. Cela signifie aussi que le code ne doit pas supposer qu’un DOM de navigateur existe dans des environnements comme le rendu côté serveur. Aucune plage de versions d’Angular n’est affirmée ici ; vérifiez la syntaxe des requêtes et les détails du cycle de vie par rapport à la version utilisée par votre application.

Obtenir la valeur du champ de saisie à l’aide d’ElementRef dans Angular

Pour lire et réinitialiser le champ de saisie, gardez ensemble les parties modèle et classe. Le modèle peut être <input #nameInput type="text" value="Ada"><button (click)="showValue()">Read</button><button (click)="resetValue()">Reset</button>. Dans la classe du composant, utilisez @ViewChild("nameInput") nameInput!: ElementRef<HTMLInputElement>;, puis définissez showValue(): void { console.log(this.nameInput.nativeElement.value); } et resetValue(): void { this.nameInput.nativeElement.value = ""; }. Le marqueur #nameInput est la référence côté modèle ; la chaîne passée à @ViewChild la sélectionne, et les liaisons des boutons invoquent les gestionnaires.

Il s’agit d’un accès direct à l’élément natif : la valeur est lue depuis l’élément de saisie ou écrite dans celui-ci. Si le champ fait partie d’un formulaire ou de l’état de l’application, préférez un contrôle de formulaire ou une liaison lorsqu’elle représente mieux le flux de données. Ces approches conservent la valeur dans le modèle d’Angular et peuvent rendre la validation et les mises à jour plus faciles à coordonner. Utilisez ElementRef lorsque la tâche exige spécifiquement d’interagir avec l’élément de saisie, et gardez l’opération petite et claire.

L’exemple JavaScript simple suivant modélise uniquement l’accès à la propriété native du champ de saisie utilisé par ces gestionnaires. Ce n’est pas un composant Angular ; l’appariement référence de modèle et @ViewChild ci-dessus montre le câblage propre au framework.

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
""

Les extraits Angular ci-dessus sont des fragments illustratifs de modèle et de TypeScript, et non des exemples exécutables de manière autonome. Placez le balisage dans le modèle du composant et la requête ainsi que les gestionnaires dans cette classe de composant ; les preuves d’exécution ne sont disponibles que pour le modèle JavaScript simple, donc aucune sortie Angular n’est affirmée.

Renderer2 d’Angular

Renderer2 est une abstraction Angular pour les opérations prises en charge sur les éléments rendus. Il se distingue d’ElementRef : ce dernier donne accès à une référence à un élément natif, tandis que Renderer2 fournit des méthodes qui effectuent des opérations comme l’ajout d’une classe ou la définition d’un style. Injectez-le dans le composant lorsqu’une opération a besoin de cette abstraction. Il ne transforme pas getElementById en une requête Angular et ne rend pas la manipulation arbitraire du DOM automatiquement sûre.

Pour définir des styles sur un élément appartenant au composant, ajoutez #styledDiv à un div dans le modèle et reliez-le à une requête telle que @ViewChild("styledDiv") styledDiv!: ElementRef<HTMLElement>;. Injectez Renderer2 dans le constructeur du composant. Dans un gestionnaire applyStyles(), appelez this.renderer.setStyle(this.styledDiv.nativeElement, "background-color", "lightblue"), puis appelez-le à nouveau avec "border" et "1px solid darkblue". Un bouton du modèle peut invoquer ce gestionnaire avec (click)="applyStyles()".

Gardez le balisage du modèle dans le modèle HTML et la requête, l’injection et le gestionnaire dans la classe TypeScript ; combiner les deux fichiers en un seul bloc de code peut obscurcir l’endroit où chaque partie appartient. Ces appels illustrent les API Angular dans leur contexte de composant et ne sont pas des exemples exécutables de manière autonome. Pour les changements de présentation ordinaires, une liaison de classe ou une liaison de style peut être plus simple et garde la condition visible dans le modèle. Utilisez Renderer2 lorsque son abstraction de rendu convient à l’opération, et évitez d’affirmer qu’il garantit la sécurité ou le comportement de détection de changements pour chaque usage.

Conclusion : manipulation du DOM dans Angular

Pour un élément appartenant à un composant, commencez par une référence de modèle et @ViewChild plutôt qu’une recherche getElementById dans tout le document. N’utilisez ElementRef et son nativeElement que lorsque le code a besoin de l’élément natif, par exemple pour lire ou réinitialiser la valeur d’un champ de saisie. Utilisez Renderer2 pour les opérations prises en charge, comme la définition d’un style. Ils complètent le modèle de composants d’Angular de différentes manières ; choisissez en fonction de la tâche et préférez les liaisons ou les contrôles de formulaire lorsqu’ils expriment plus clairement la vue et le flux de données souhaités.