2017-10-10 89 views
-1

中描述的那樣工作我想要獲取元素的offsetLeft,但是我得到的值不正確,除非使用setTimeout。Angular 2指令的生命週期鉤子(ngAfterContentInit)不能像文檔

基本上在指令中我有這樣的:「生命週期掛鉤後指令的內容已經完全初始化被稱爲」

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

文檔指出此爲ngAfterContentInit。但不是返回40px它返回8px(甚至不知道它在哪裏得到8)。

任何想法,爲什麼它不工作?是否因爲該指令的根元素不被視爲該指令的一部分,只有它的孩子是?

回答

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)後都會調用該鉤子。這意味着它必須快速發展,否則會對用戶界面造成巨大的負面影響。 –

+0

我必須不同意你的看法。無論如何,你會使用它或者不使用Angular。如果你在afterviewchecked中設置havel訂閱或者計算,那麼你在裏面放的是重要的,那麼是的,這不是一個好主意。此外,它受到條件「保護」。在其他方面,我非常感染evrything,並且有超時管理 – Vega

+0

我沒有得到你不同意的 - 這實際上就是我所說的。 :)我的意思是這裏有兩件事:a)這個處理程序必須非常輕 - 正如你所認同的那樣 - 因爲它被稱爲很多,而且「測量」DOM元素有時會是相對較大的操作; b)它不止一次發射(實際上更多!),這可能不是OP想要的(這是他們想要的)。這就是我想說的,也許我沒有表達得很清楚,對此抱歉。至於超時 - 我不喜歡超時,但有時我們不得不使用這些東西,因爲我們沒有更好的東西... –

相關問題