How should I configure the new Angular 8 view child?
@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;
vs
@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;
Which is better? When should I use static:true
vs static:false
?
In most cases you will want to use {static: false}
. Setting it like this will ensure query matches that are dependent on binding resolution (like structural directives *ngIf, etc...
) will be found.
Example of when to use static: false
:
@Component({
template: `
<div *ngIf="showMe" #viewMe>Am I here?</div>
<button (click)="showMe = !showMe"></button>
`
})
export class ExampleComponent {
@ViewChild('viewMe', { static: false })
viewMe?: ElementRef<HTMLElement>;
showMe = false;
}
The static: false
is going to be the default fallback behaviour in Angular 9. Read more here and here
The { static: true }
option was introduced to support creating embedded views on the fly. When you are creating a view dynamically and want to acces the TemplateRef
, you won't be able to do so in ngAfterViewInit
as it will cause a ExpressionHasChangedAfterChecked
error. Setting the static flag to true will create your view in ngOnInit.
Nevertheless:
In most other cases, the best practice is to use
{static: false}
.
Be aware though that the { static: false }
option will be made default in Angular 9. Which means that setting the static flag is no longer necessary, unless you want to use the static: true
option.
You can use the angular cli ng update
command to automatically upgrade your current code base.
For a migration guide and even more information about this, you can check here and here
What is the difference between static and dynamic queries?
The static option for @ViewChild() and @ContentChild() queries determines when the query results become available.
With static queries (static: true), the query resolves once the view has been created, but before change detection runs. The result, though, will never be updated to reflect changes to your view, such as changes to ngIf and ngFor blocks.
With dynamic queries (static: false), the query resolves after either ngAfterViewInit() or ngAfterContentInit() for @ViewChild() and @ContentChild() respectively. The result will be updated for changes to your view, such as changes to ngIf and ngFor blocks.