Pour une raison quelconque, mon @ViewChild dans mon Angular 5 App ne fonctionne pas . Je l'ai défini comme suit dans mon composant:
case-detail.component.html:
<div class="inner-tab-content" #innerTabContent>
<!-- // more content here -->
</div>
J'ai implémenté @ViewChild
dans mon contrôleur (au-dessus du constructeur) comme ceci:
case-detail.component.ts
@ViewChild('innerTabContent') tabContentElement: ElementRef;
Et je veux y accéder ici dans le composant: case-detail.component.ts
ngAfterViewInit() {
console.log("scroll top: " + this.tabContentElement.nativeElement);
}
J'ai implémenté l'interface AfterViewInit
. ngAfterViewInit () est appelé correctement. Cependant, this.tabContentElement
est toujours undefined
.
Toute aide est grandement appréciée :)
ViewChild()
fonctionne correctement avec la dernière version de plunker Angular avec le scénario que vous décrivez.
Démonstration dans ce dossier: https://plnkr.co/edit/KzWnkE5Hvp7NUow6YAxy
composant:
ngAfterViewInit() {
console.log(this.testView); // correctly outputs the element in console, not undefined
}
Vérifiez que ElementRef et ViewChild sont correctement importés de '@ angular/core'
Votre élément pourrait tout simplement ne pas être là au moment de AfterViewInit (dans le cas où il y aurait un *ngIf
, par exemple. (Semble le cas d'après vos commentaires)
Dans ce dernier cas, vous pouvez utiliser un élément wrapper et ViewChildren
, qui émet un événement lorsqu'un nouvel élément enfant est ajouté - pour plus d'informations sur la documentation, cliquez ici: https://angular.io/api/core/ViewChildren
notez qu'il peut y avoir un problème avec div
en natif selon cette question: @ViewChildren n'est pas mis à jour avec des éléments DOM ajoutés dynamiquement , mais cela peut être contourné en utilisant un nouveau composant qui encapsule votre div, par exemple.
Vous pouvez également utiliser un délai d’attente pour que le composant soit rendu. Je dois dire que je trouve cette solution 'sale', mais content que cela fonctionne pour vous :)
Cependant, même si vous accédez au composant enfant dans la AfterViewInit
, le @ViewChild
retournait toujours toujours la null
. Le problème peut être causé par la *ngIf
ou une autre directive.
La solution consiste à utiliser le @ViewChildren
au lieu de @ViewChild
et à souscrire l'abonnement changes
qui est exécuté lorsque le composant est prêt.
Par exemple, si vous voulez accéder au composant enfant ParentComponent
dans le composant parent MyComponent
.
import { Component, ViewChildren, AfterViewInit, QueryList } from '@angular/core';
import { MyComponent } from './mycomponent.component';
export class ParentComponent implements AfterViewInit
{
//other code emitted for clarity
@ViewChildren(MyComponent) childrenComponent: QueryList<MyComponent>;
public ngAfterViewInit(): void
{
this.childrenComponent.changes.subscribe((comps: QueryList<MyComponent>) =>
{
// Now you can access to the child component
});
}
}
Une réponse différente à cette question serait parfois, le composant enfant n'est toujours pas rendu, lorsque vous y accédez. Pour moi, c'était dû à un * ngIf, de sorte que la composante enfant n'y est toujours pas. À titre d'exemple,
<div *ngIf="check">
<app-child-item></app-child-item>
</div>
Et dans votre fichier .ts parent, vous essayez d'accéder à childItem alors que check est défini sur false.