Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular v8 - @ViewChild static true or false

Angular v8 has just been released. Although it's mostly backward compatible, there's some Breaking Changes.

According to Angular's Changelog one core change is (and I quote):

"In Angular version 8, it's required that all @ViewChild and @ContentChild queries have a 'static' flag specifying whether the query is 'static' or 'dynamic'."

It's also state that in most cases just setting { static: false } will do the trick.

@ViewChild('selectorName', { static: false }) varName: any;

My question is when should I set this attribute (static) to be true? and how will it effect my application???

like image 981
Gil Epshtain Avatar asked Jul 09 '19 12:07

Gil Epshtain


People also ask

Why is static true in ViewChild?

If your ChildComponent is always available on the page, and is never hidden. Then you can use *either* static false or static true. But setting static to true is more performant, and gives you earlier access to the component (if required).

What does @ViewChild does in Angular?

The @ViewChild decorator allows us to inject into a component class references to elements used inside its template, that's what we should use it for. Using @ViewChild we can easily inject components, directives or plain DOM elements.

What is the difference between ViewChild () and ContentChild ()?

ViewChild is used to select an element from component's template while ContentChild is used to select projected content.

What is difference between ViewChild and ViewChildren?

Working with @ViewChildren is similar to @ViewChild, but the difference between the two is @ViewChildren provides a list of element references rather than returning a single reference. It is used to reference multiple elements. We can then iterate the list of the element referenced by the variable.


1 Answers

Use { static: true } when you want to access the ViewChild in ngOnInit.

Use { static: false } will be accessible only in ngAfterViewInit. This is also what you want to do for when you have a structural directive (*ngIf etc.) in your template.

In most cases { static: false } will work.

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss']
})
export class ExampleComponent implements OnInit, AfterViewInit
{
  @ViewChild('elementA', { static: true }) elementStatic: ElementRef<HTMLElement>;
  @ViewChild('elementB', { static: false }) elementDynamic: ElementRef<HTMLElement>;
        
  public ngOnInit(): void
  {
    this.elementStatic.nativeElement; // Ok
    this.elementDynamic.nativeElement; // ERROR TypeError: Cannot read property 'nativeElement' of undefined 
  }
  
  public ngAfterViewInit(): void
  {
    this.elementStatic.nativeElement; // Ok
    this.elementDynamic.nativeElement; // Ok
  }
}
<div #elementA>A</div>
<div #elementB>B</div>

Update: Starting from Angular v9.x static has a default value of false.
Read more at: https://angular.io/api/core/ViewChild#viewchild

like image 72
Gil Epshtain Avatar answered Nov 15 '22 15:11

Gil Epshtain