[英]How to check whether ngIf has taken effect
我在做什么
我有一個基於簡單布爾值使用*ngIf
隱藏/顯示的組件。 當組件變得可見時,我想將焦點應用於其模板中的子元素。
問題
如果我翻轉布爾值,組件會正確顯示,但如果我嘗試使用this._elRef.nativeElement.querySelector("div#test")
獲取對子元素的引用,它就會返回null
。 如果我等待幾秒鍾,相同的代碼將返回對我所期望的元素的引用。
推測
我假設在翻轉布爾角后經過整個渲染周期以顯示新的可見組件,並且在我在下一行中應用querySelector()
時尚未完成。
我想知道什么
所以我想知道的是,我如何確定我的ngIf
已經生效並且元素是他們在DOM中的選擇?
是否有針對ngIf
的回調或者我可以強制視圖更新並從中獲取回調嗎?
我希望這是有道理的。 這是一個漫長的一天(漫長的一周),我太累了。
謝謝大家
如果它有幫助,我正在使用Angular2 v2.0.0-beta.15
如果將布爾值翻轉為true
並在下一行代碼中嘗試獲取對由NgIf控制的組件或DOM元素的引用......那么,該組件或DOM元素尚不存在。 Angular不會與您的代碼並行運行。 您的JavaScript回調必須完成,然后運行Angular(更改檢測),這將注意布爾值更改並創建組件或DOM元素並將其插入DOM。
要解決您的問題,請在翻轉布爾值后調用setTimeout(callbackFn, 0)
。 這會將callbackFn
添加到JavaScript消息隊列中 。 這將確保Angular(更改檢測)在回調函數之前運行。 因此,當您的callbackFn
執行時,您想要聚焦的元素現在應該存在。 使用setTimeout(..., 0)
可確保在下一輪JavaScript事件循環中 callbackFn
。
在討論AfterView *鈎子時,在LifeCycle鈎子開發指南中使用這種使用setTimeout(..., 0)
技術。
如果您需要更多詳細信息,請參閱以下幾個示例:
focus
這個問題相當陳舊,當時的解決方案當時可能還沒有。
setTimeout()
方法完全可行,但具有明顯的缺點。 如果你只是設置一個類來定位一個元素,就像我一樣,你會得到一個跳躍的結果,因為代碼是在angular循環之后執行的。
使用ChangeDetectorRef
會生成不跳轉的結果。
所以不是這樣的:
class Foo {
public isDisplayed = false;
constructor(@Inject(ElementRef) private elementRef: ElementRef) {
}
public someMethod(): void {
this.isDisplayed = true;
setTimeout(() => {
const child = this.elementRef.nativeElement.querySelector('.child-element');
// ...
});
}
}
你可以這樣做:
class Foo {
public isDisplayed = false;
constructor(@Inject(ElementRef) private elementRef: ElementRef,
@Inject(ChangeDetectorRef) private changeDetectorRef: ChangeDetectorRef) {
}
public someMethod(): void {
this.isDisplayed = true;
this.changeDetectorRef.detectChanges();
const child = this.elementRef.nativeElement.querySelector('.child-element');
// ...
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.