[Vidéo] Utilisez les signaux, c'est le futur d'Angular !

Dans cette vidéo de 3 minute, découvrez pourquoi les signaux sont essentiels pour l'avenir du développement web et apprenez les 3 fonctions: signal / computed / effect

Skip to content

Comment utiliser @ViewChild dans un composant dans Angular ?

La directive @ViewChild est utilisée pour accéder à un élément du DOM ou à un composant enfant dans un composant Angular. Elle permet de récupérer une référence à un élément HTML ou à un composant enfant dans le template du composant, ce qui permet de manipuler directement l'élément ou le composant dans le code TypeScript.


Voici comment utiliser @ViewChild dans un composant Angular :

  1. Déclarez @ViewChild en haut de votre classe de composant :
ts
import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <input type="text" #myInput>
  `,
})
export class AppComponent {
  @ViewChild('myInput') input!: ElementRef;
}
  1. Vous pouvez maintenant accéder à l'élément de votre template HTML dans votre composant en utilisant la propriété input. Par exemple, vous pouvez accéder à la valeur de l'input en utilisant this.input.nativeElement.value.

Voici un exemple complet et concret de l'utilisation de @ViewChild dans un composant Angular :

ts
import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <input type="text" #myInput>
    <button (click)="changeValue()">Modifier la valeur de l'input</button>
  `
})
export class AppComponent {
  @ViewChild('myInput') input!: ElementRef;

  changeValue() {
    this.input.nativeElement.value = 'Nouvelle valeur';
  }
}

Dans cet exemple, lorsque vous cliquerez sur le bouton, la valeur de l'input sera modifiée en "Nouvelle valeur".

ViewChild avec static: true

Par défaut, @ViewChild utilise static: false, ce qui signifie que la liaison se fait après l'initialisation du composant. Si vous avez besoin d'accéder à l'élément dès la création du composant, vous pouvez utiliser static: true :

ts
import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <input type="text" #myInput>
  `
})
export class AppComponent implements OnInit {
  @ViewChild('myInput', { static: true }) input!: ElementRef;

  ngOnInit() {
    // Vous pouvez accéder dans ngOnInit, ce qui n'était pas possible avec static: false
    console.log(this.input.nativeElement.value);
  }
}

ViewChild avec selecteur de composant

Vous pouvez également utiliser @ViewChild pour accéder à un composant enfant dans un composant parent. Pour cela, vous devez spécifier le type du composant enfant dans le décorateur @ViewChild :

ts
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <app-child />
  `,
  imports: [ChildComponent]
})
export class AppComponent implements AfterViewInit {
  @ViewChild(ChildComponent) childComponent!: ChildComponent;

  ngAfterViewInit() {
    // Vous pouvez accéder au composant enfant ici
    this.childComponent.someMethod();
  }
}
ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h1>Composant enfant</h1>
  `
})
export class ChildComponent {
  someMethod() {
    console.log('Méthode du composant enfant appelée');
  }
}

ViewChild avec l'option read

Vous pouvez également utiliser l'option read pour accéder à des éléments spécifiques dans un composant ou un directive appliquée à un élément:

ts
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { NgClass } from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <div #myDiv [ngClass]="cssClass">Contenu de la div</div>
  `,
  imports: [NgClass]
})
export class AppComponent implements AfterViewInit {
  @ViewChild('myDiv', { read: NgClass }) myDiv!: NgClass;
  cssClass = '';

  ngAfterViewInit() {
    // Vous pouvez accéder à la directive NgClass appliquée à la div ici
    this.myDiv.add('highlight');
  }
}

Dans cet exemple, nous utilisons @ViewChild avec l'option read pour accéder à la directive NgClass appliquée à la div. Nous pouvons ensuite appeler la méthode add de la directive pour ajouter une classe CSS à la div.

ViewChild avec ng-template

Vous pouvez également utiliser @ViewChild pour accéder à un élément ng-template dans un composant :

ts
import { Component, ViewChild, TemplateRef } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <ng-template #myTemplate>
      <p>Contenu du template</p>
    </ng-template>
  `
})
export class AppComponent {
  @ViewChild('myTemplate') myTemplate!: TemplateRef<any>;

  ngAfterViewInit() {
    // Vous pouvez accéder au contenu du template ici
    console.log(this.myTemplate);
  }
}

L'intérêt de cette approche est de pouvoir accéder au contenu du template et de l'utiliser dynamiquement dans le composant. Par exemple, vous pouvez insérer le contenu du template dans un élément du DOM en utilisant ViewContainerRef et TemplateRef:

ts
import { Component, ViewChild, TemplateRef, ViewContainerRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <ng-template #myTemplate>
      <p>Contenu du template</p>
    </ng-template>
    <div #container></div>
  `
})
export class AppComponent implements AfterViewInit {
  @ViewChild('myTemplate') myTemplate!: TemplateRef<any>;
  @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;

  ngAfterViewInit() {
    // Insérer le contenu du template dans le conteneur
    this.container.createEmbeddedView(this.myTemplate);
  }
}

Mais quels sont les cas d'usage de @ViewChild ? Quelques idées

Voici dix cas d'utilisation réels de la directive @ViewChild dans Angular, sans inclure de code :

  1. Accès à un élément du DOM :

    • Utiliser @ViewChild pour accéder directement à un élément HTML dans le composant pour manipuler ses propriétés (par exemple, focus, changement de style, etc.).
  2. Interaction avec des composants enfants :

    • Utiliser @ViewChild pour appeler des méthodes publiques ou accéder aux propriétés d'un composant enfant depuis le composant parent.
  3. Gestion des formulaires :

    • Accéder à un formulaire Angular pour réinitialiser le formulaire, valider les champs ou obtenir des valeurs de champ directement.
  4. Accès à des directives :

    • Accéder à une directive appliquée sur un élément HTML pour modifier son comportement.
  5. Intégration de bibliothèques tierces :

    • Utiliser @ViewChild pour intégrer et contrôler des bibliothèques JavaScript tierces (par exemple, des plugins jQuery) en manipulant directement le DOM.
  6. Création de composants dynamiques :

    • Utiliser @ViewChild pour obtenir une référence à une directive ng-template et créer dynamiquement des composants à cet emplacement.
  7. Déclenchement de changements de détection personnalisés :

    • Utiliser @ViewChild pour accéder aux éléments qui ne déclenchent pas automatiquement la détection des changements, et appeler manuellement changeDetectorRef.detectChanges().
  8. Contrôle des animations :

    • Accéder aux éléments HTML ou aux composants pour contrôler les animations (démarrage, arrêt, pause) en fonction de certaines conditions ou événements.
  9. Manipulation des événements utilisateur :

    • Attacher des écouteurs d'événements personnalisés aux éléments du DOM pour des interactions utilisateur plus complexes qui ne sont pas gérées par Angular par défaut.
  10. Test et Debugging :

    • Utiliser @ViewChild pour accéder aux composants enfants ou aux éléments DOM pendant les tests pour vérifier leur état ou simuler des interactions utilisateur.

En août, Recevez des nouvelles libraries Angular 🌟 qui peuvent vous être utiles pour booster vos projets. Inscrivez-vous maintenant et découvrez les dernières tendances et outils Angular directement dans votre boîte mail !