2017-10-10 1 views
-1

要素のoffsetLeftを取得しようとしていますが、setTimeoutを使用しない限り不正な値が返されます。 ngAfterContentInitためドキュメントに記載されているように角2のディレクティブのライフサイクルフック(ngAfterContentInit)が機能しない

ngAfterContentInit() { 
    console.log(this.el.nativeElement.offsetLeft); 
} 

ドキュメントの状態この「ディレクティブの内容が完全に初期化された後に呼び出されるライフサイクルフックを。」:私はこれを持っているディレクティブで基本的に

。しかし、40pxを返す代わりに、それは8pxを返します(それがどこにあるかは分かりません)。

なぜ機能しないのですか?ディレクティブのルート要素がディレクティブの一部とみなされておらず、その子のみが存在するからですか?

答えて

1

私は、これは動作するはずだと思う:

ngAfterContentInit() { 
    setTimeout(() => { 
     console.log(this.el.nativeElement.offsetLeft); 
    }); 
} 

現時点でngAfterContentInit()火災の子供たちがまだレンダリングされませんので、これはある - ので、あなたがそれを行うには、角度の時間を与える必要があります。

+0

それがないが、それはハック見えるんが、それはまた、非常にハック – yodalr

+0

@yodalrに見える - それは実際にではありません。 :)これはちょうど角度の働きです。ここでの主なポイントは、あなたが**後でコンテンツを見ることができる**ということです。これは一般に、あなたが行うことを確認する最も簡単な方法です。しかし、親コンポーネントがレンダリングされてから長時間のHTTPリクエスト、つまり長い時間が経過してコンテンツがレンダリングされる場合、適切な時点を選択する唯一の信頼できる方法は、コンテンツ内のコンポーネントと明示的に通信し、準備ができていることを意味します。 –

0

あなたは、タイムアウトを使用したい、この構文でAfterViewCheckedを使用しない場合:

start = true; 
..... 
ngAfterContentChecked() { 
    if (this.start){ 
     console.log(this.el.nativeElement.offsetLeft); 
    } 
    this.start = false; 
} 
+0

私は、この後続のngDoCheck()の後にこのフックが呼び出されていることに気付くことはないと思っています(角度のドキュメントが示唆しているように:https://angular.io/guide/lifecycle-hooks)。これは、ただ速くすばやくなければならないことを意味します。そうしなければ、UIに大きなマイナスのパフォーマンスの影響を与える可能性があります。 –

+0

私はあなたに同意しなければなりません。あなたはそれを使用するかどうかはとにかくAngularはとにかくあなたのライフサイクルを実行します。それはあなたがその問題の中に置いたものです。あなたが妊娠していないかどうかを確認した後、さらに、それは条件によって「保護されている」。反対側では、私はタイムアウトで管理されているevrythingと非常に腐敗しています – Vega

+0

私はあなたが同意していないものを得ていない - これは本質的に私が言っているものです。 :)私はここで2つのことを意味しました:a)このハンドラは非常に軽くなければなりません - あなたが同意したように - それはたくさん呼ばれ、DOM要素を "測定する" b)それは、OPが望んでいないものである可能性がある(実際にはそれが分かります)複数回(実際には!)発火します。それは私が言いたかったことです、私はそれを非常に明確に表現していないかもしれません。タイムアウトに関して - 私はタイムアウトが好きではありませんが、時には私たちはもっと良いものを持っていないので、そのようなものを使用しなければなりません。 –

関連する問題