Table of Contents
Introduction
Dans cet article, vous allons vous expliquer ce qu'est un décorateur ViewChild d'Angular.
Il se peut que dans certaines situations vous souhaitiez accéder à une directive, un composant enfant ou un élément DOM à partir d'une catégorie de composants parent. Le décorateur ViewChild renvoie le premier élément qui correspond à un sélecteur de référence de directive, de composant ou de modèle donné.
Utilisation de ViewChild avec des directives
ViewChild permet d'accéder aux directives.
Supposons que nous ayons une SharkDirective.
L'idéal serez que vous puissiez utiliser @angular/cli pour générer votre directive :
ng generate directive shark
Ou alors, il vous faudra l'ajouter manuellement à app.module.ts :
[label app.module.ts]
<^>import { SharkDirective } from './shark.directive';<^>
...
@NgModule({
declarations: [
AppComponent,
<^>SharkDirective<^>
],
...
})
Notre directive recherchera les éléments avec l'attribut appShark et ajoutera le texte dans l'élément avec le terme Shark :
[label shark.directive.ts]
import {
Directive,
ElementRef,
Renderer2
} from '@angular/core';
@Directive(
{ selector: '[appShark]' }
)
export class SharkDirective {
creature = 'Dolphin';
constructor(elem: ElementRef, renderer: Renderer2) {
let shark = renderer.createText('Shark ');
renderer.appendChild(elem.nativeElement, shark);
}
}
Ensuite, nous allons ajouter un Shark à Fin en l'utilisant dans le modèle de composant :
[label app.component.html]
<span <^>appShark<^>>Fin!</span>
Lorsque vous visualiserez l'application dans un navigateur, l'affichage sera le suivant :
[secondary_label Output]
Shark Fin!
Maintenant, nous pouvons accéder à la variable d'instance creature de SharkDirective. Elle configurera une variable extraCreature avec sa valeur :
[label app.component.ts]
import {
Component,
ViewChild,
AfterViewInit
} from '@angular/core';
import { SharkDirective } from './shark.directive';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
extraCreature: string;
@ViewChild(SharkDirective)
set appShark(directive: SharkDirective) {
this.extraCreature = directive.creature;
};
ngAfterViewInit() {
console.log(this.extraCreature); // Dolphin
}
}
Ici, nous avons utilisé une méthode de réglage pour configurer la variable extraCreature. Notez que nous attendons que le hook de cycle de vie AfterViewInit ait accès à notre variable, car c'est à ce moment-là que les composants et les directives enfant seront disponibles.
Lorsque nous consultons l'application dans un navigateur, nous voyons encore apparaître "Shark Fin!" . Cependant, dans le journal de la console, il s'affichera de la manière suivante :
[secondary_label Output]
Dolphin
Le composant parent a pu accéder à la valeur depuis la directive.
Utilisation de ViewChild avec les éléments DOM
ViewChild permet d'accéder aux éléments DOM natifs qui ont une variable de référence de modèle.
Supposons que nous ayons un <input> dans notre modèle avec la variable de référence #someInput :
[label app.component.html]
<input <^>#someInput<^> placeholder="Your favorite sea creature">
Maintenant, nous pouvons accéder à <input> avec ViewChild et configurer la value :
[label app.component.ts]
import {
Component,
ViewChild,
AfterViewInit,
ElementRef
} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('someInput') someInput: ElementRef;
ngAfterViewInit() {
this.someInput.nativeElement.value = 'Whale!';
}
}
Lorsque ngAfterViewInit se déclenche, la valeur de notre <input> sera configurée :
[secondary_label Output]
Whale!
Le composant parent a réussi à configurer la valeur de l'élément DOM enfant.
Utilisation de ViewChild avec des composants enfant
ViewChild permet d'accéder à un composant enfant et appeler des méthodes ou d'accéder à des variables d'instance qui sont disponibles pour l'enfant.
Supposons que nous ayons un ChildComponent. L'idéal serez que vous puissiez utiliser @angular/cli pour générer votre composant :
ng generate component child --flat
Ou alors, il vous faudra créer les fichiers child.component.css et child.component.html et l'ajouter manuellement à app.module.ts :
[label app.module.ts]
<^>import { ChildComponent } from './child.component';<^>
...
@NgModule({
declarations: [
AppComponent,
<^>ChildComponent<^>
],
...
})
Nous allons ajouter une méthode whoAmI à ChildComponent qui renverra le message suivant :
[label child.component.ts]
whoAmI() {
return 'I am a child component!';
}
Ensuite, nous allons référencer le composant dans notre modèle d'application :
[label app.component.html]
<app-child>child works!</app-child>
Maintenant, nous pouvons appeler la méthode whoAmI de notre catégorie de composants parent avec ViewChild de la manière suivante :
[label app.component.ts]
import {
Component,
ViewChild,
AfterViewInit
} from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
@ViewChild(ChildComponent) child: ChildComponent;
ngAfterViewInit() {
console.log(this.child.whoAmI()); // I am a child component!
}
}
Lorsque vous visualiserez l'application dans un navigateur, le journal de la console s'affichera :
[secondary_label Output]
I am a child component!
Le composant parent a réussi à appeler la méthode whoAmI du composant enfant.
Conclusion
Vous avez appris à utiliser ViewChild pour accéder à une directive, à un composant enfant et à un élément DOM dans une catégorie de composants parent.
Si la référence est remplacée de manière dynamique par un nouvel élément, ViewChild mettra à jour automatiquement sa référence.
Dans le cas où vous souhaitez accéder à plusieurs composants enfant, utilisez plutôt ViewChildren.
Si vous souhaitez en savoir plus sur Angular, consultez notre page thématique Angular pour des exercices et des projets de programmation.