What is the most elegant way to get @ViewChild after corresponding element in template was shown?
Below is an example. Also Plunker available.
Component.template.html:
<div id="layout" *ngIf="display">   <div #contentPlaceholder></div> </div> Component.component.ts:
export class AppComponent {      display = false;     @ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;      show() {         this.display = true;         console.log(this.viewContainerRef); // undefined         setTimeout(() => {             console.log(this.viewContainerRef); // OK         }, 1);     } } I have a component with its contents hidden by default. When someone calls show() method it becomes visible. However, before Angular 2 change detection completes, I can not reference to viewContainerRef. I usually wrap all required actions into setTimeout(()=>{},1) as shown above. Is there a more correct way?
I know there is an option with ngAfterViewChecked, but it causes too much useless calls.
Use a setter for the ViewChild:
 private contentPlaceholder: ElementRef;   @ViewChild('contentPlaceholder') set content(content: ElementRef) {     if(content) { // initially setter gets called with undefined         this.contentPlaceholder = content;     }  } The setter is called with an element reference once *ngIf becomes true.
Note, for Angular 8 you have to make sure to set { static: false }, which is a default setting in other Angular versions:
 @ViewChild('contentPlaceholder', { static: false }) Note: if contentPlaceholder is a component you can change ElementRef to your component Class:
  private contentPlaceholder: MyCustomComponent;    @ViewChild('contentPlaceholder') set content(content: MyCustomComponent) {      if(content) { // initially setter gets called with undefined           this.contentPlaceholder = content;      }   } An alternative to overcome this is running the change detector manually.
You first inject the ChangeDetectorRef:
constructor(private changeDetector : ChangeDetectorRef) {} Then you call it after updating the variable that controls the *ngIf
show() {         this.display = true;         this.changeDetector.detectChanges();     } If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With