Angular - 5.12-Access model and DOM with @ViewChild
Local references are perfect to grab a DOM element from within a template, but they are invisible to the TypeScript class. When the component code itself needs to read or manipulate the DOM, Angular gives us @ViewChild(): a decorator that queries the template and exposes either an element reference or a child component instance as a class property.
Two flavours of @ViewChild
@ViewChild('localRef')— query a template by its local reference name. The result is anElementRefwrapping the native DOM element.@ViewChild(ChildComponent)— query by component type. The result is the actual child component instance, so you can read its public state or call its methods.- By default the reference resolves after the view is initialised, so reading it inside
ngAfterViewInitis the safest option.
@ViewChild('serverNameInput') serverNameInput!: ElementRef<HTMLInputElement>;
onAdd() {
const value = this.serverNameInput.nativeElement.value;
console.log(value);
}
Reaching into nativeElement is powerful but should remain the last resort. Direct DOM access bypasses Angular's change detection and breaks server-side rendering. Whenever possible, prefer property and event bindings, or two-way bindings with [(ngModel)]. @ViewChild is the right tool when you need to focus an input, scroll a container into view, integrate with a third-party library, or call a method on a child component such as open() on a modal.
The same idea applies to lists of children with @ViewChildren, and Angular also exposes @ContentChild/@ContentChildren for projected content. The vocabulary is consistent: the View* family targets the component's own template, the Content* family targets what is projected via ng-content.