何らかの理由で、私のAngular 5アプリの@ViewChildは機能しません。コンポーネントで次のように定義しました。
case-detail.component.html:
<div class="inner-tab-content" #innerTabContent>
<!-- // more content here -->
</div>
私は(コンストラクタの上にある)コントローラに@ViewChild
を次のように実装しました:
case-detail.component.ts
@ViewChild('innerTabContent') tabContentElement: ElementRef;
そして、私はコンポーネントでここにアクセスしたいと思います:case-detail.component.ts
ngAfterViewInit() {
console.log("scroll top: " + this.tabContentElement.nativeElement);
}
AfterViewInit
インターフェースを実装しました。 ngAfterViewInit()が正しく呼び出されます。ただし、this.tabContentElement
は常にundefined
です。
どんな助けでも大歓迎です:)
ViewChild()
は、最新のプランカーAngularバージョンで正常に機能し、説明したシナリオに対応しています。
このプランカーでのデモ: https://plnkr.co/edit/KzWnkE5Hvp7NUow6YAxy
コンポーネント:
ngAfterViewInit() {
console.log(this.testView); // correctly outputs the element in console, not undefined
}
ElementRefとViewChildが '@ angular/core'から正しくインポートされていることを確認します。
AfterViewInitの時点で要素が存在しない可能性があります(*ngIf
、例えば。(あなたのコメントによるとケースがそうです)
後者の場合は、ラッパー要素とViewChildren
を使用できます。これにより、新しい子要素が追加されたときにイベントが発生します-ドキュメントの詳細はこちら: https://angular.io/api/core/ViewChildren
この質問に従ってネイティブdiv
に問題がある可能性があることに注意してください: @ ViewChildrenは動的に追加されたDOM要素で更新されません ですが、これは新しいコンポーネントを使用することで回避できますたとえば、divをラップします。
または、タイムアウトを使用して、コンポーネントがレンダリングされるのを待つこともできます。私はこの解決策を「汚い」と思っていると言わなければなりませんが、それがあなたのために働くのはうれしいです:)
ただし、AfterViewInit
の子コンポーネントにアクセスした場合でも、@ViewChild
はまだnull
を返していました。問題は*ngIf
またはその他のディレクティブ。
解決策は@ViewChildren
の代わりに @ViewChild
およびコンポーネントの準備ができたときに実行されるchanges
サブスクリプションをサブスクライブします。
たとえば、親コンポーネントParentComponent
の場合、子コンポーネント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
});
}
}
この質問に対する別の答えは、アクセスしたときに、子コンポーネントがまだレンダリングされない場合があります。私にとっては、子コンポーネントがまだ存在しない* ngIfが原因でした。例として、
<div *ngIf="check">
<app-child-item></app-child-item>
</div>
そして、親の.tsファイルで、checkがfalseに設定されているときにchildItemにアクセスしようとします。