Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
829 views
in Technique[技术] by (71.8m points)

angular - How to check whether ngIf has taken effect

What I'm Doing
I have a component that hides/shows using *ngIf based on a simple Boolean. When the component becomes visible I want to apply focus to a child element within its template.

The Problem
If I flip the Boolean value the component shows correctly but if I then try and get a reference to the child element using this._elRef.nativeElement.querySelector("div#test") it just comes back null. If I wait a few seconds the same code will return the reference to the element as I expected.

Speculation
I'm assuming that after flipping the Boolean angular goes through a whole rendering cycle to reveal the newly visible component and that this has not finished by the time I apply the querySelector() in the next line.

What I'd Like To Know
So what I'm wondering is, how can I be sure that my ngIf has taken effect and the elements are their in the DOM to be selected?
Is there such a thing as a callback for ngIf or can I force the view to update and get a callback from that?

I hope this makes sense. It has been a long day (long week) and I'm super tired.
Thanks all

If it helps, I'm using Angular2 v2.0.0-beta.15

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you flip the boolean value to true and in the next line of code you try to get a reference to the component or DOM element controlled by NgIf... well, that component or DOM element doesn't exist yet. Angular doesn't run in parallel with your code. Your JavaScript callback has to finish, then Angular (change detection) runs, which will notice the boolean value change and create the component or DOM element and insert it into the DOM.

To fix your issue, call setTimeout(callbackFn, 0) after you flip the boolean value. This adds your callbackFn to the JavaScript message queue. This will ensure that Angular (change detection) runs before your callback function. Hence, when your callbackFn executes, the element you want to focus should now exist. Using setTimeout(..., 0) ensures that your callbackFn gets called in the next turn of the JavaScript event loop.

This technique of using setTimeout(..., 0) is used in the LifeCycle hooks dev guide when discussing the AfterView* hooks.

Here are a few other examples, if you need more details:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...