How To Use ViewChild in Angular to Access a Child Component
Angular's ViewChild decorator enables accessing and manipulating child components, directives, or DOM elements within a parent component. It queries the first matching element in the component tree, allowing interaction with its properties and methods.
@ViewChild
- To query the element token or selector,
- Returns single element only
- The best place to operate on the ViewChild query is the ngAfterViewInit lifecycle hook
Syntax:
html:
In the above example, you can access inputElement inside the component using the ViewChild query. inputElement will be read by the browser DOM as by default it will detect ElementRef if just the string selector is mentioned. Similar way you can see in the second query, we query by the MyComponent token.
Metadata Properties
- selector:
The directive token or selector name. - read:
Used by change detector to read a different token while querying. - static:
true to resolve query results before change detection runs, false to resolve after change detection. (Defaults to false).
@ViewChildren
- It helps to query multiple views of DOM at the same time
- Default query token would be ElementRef when just selector is passed.
- It returns results in QueryList format (collection)
- In addition to that, any view DOM updates, removes or moves will be updated inside the ViewChildren angular query.
Metadata Properties
- selector - The directive token or the name used for querying.
- read - Used for reading a different token from the queried elements.
Syntax:
html:
In the above HTML input element is drawn over n times using *ngFor, these all elements will be present inside the inputElements component variable.
Using ViewChild with Directives
- Ask the change detector to query by Directive token
- Access public properties
- Can execute public methods
Example
Directive:
Component:
In the above example, we've queried using the MyDirective token. After the ngAfterViewInit lifecycle hook is triggered, we called the doSomething() method from my-component. That is how we can read properties or call methods from queried view.
Note:
Using the same manner, we can query by token of either Component or Service.
Using ViewChild with DOM Elements
- Here specifically let's change the detector to look up with the ElementRef type.
- You can optionally pass { read: ElementRef } metadata inside the @ViewChild angular decorator function.
- Interestingly, we're have wrote #inputElement on input element, #variableName is called as local template variable.
In the above example, we queried by token inputElement selector, and specifically, we're telling the change detector to read the ElementRef token.
Using ViewChild with Template and ViewContrainerRef
ViewContrainerRef
- ViewContainerRef query can only be made on the ng-container, component, or directive token.
- Pass { read: ViewContrainerRef } object inside @ViewChild angular decorator metadata.
TemplateRef
- TemplateRef query can only be made on the ng-template element.
- Pass { read: TemplateRef } object inside @ViewChild angular decorator metadata.
my.component.ts:
The requirement is, on click of a button Dynamic Content, it should populate ng-template content. Inside MyComponent we've used @ViewChild with TemplateRef and ViewContainerRef tokens to grab the respective view DOM. With the click of the Dynamic Content button, we populate content inside the placeholder by calling the .createEmbededView method.
Notes:
_ViewContainerRef: can act as a placeholder for content, we can insert, or remove dynamic content into it. We can use methods like createComponent, createEmbededView, insert, move, etc. methods.
Using ViewChild with Child Components
To understand this mechanism of accessing Child Components from parent components, we would take baby steps to clear the fundamentals behind the concept.
Generate a Parent Component Named "employee"
Run the below Angular CLI commands to generate the employee component.
Employee Component Folder Structure:
Generate a Child Component Named "salary"
Run the CLI command to generate the salary component as well.
Salary Component Folder Structure:
Open and Edit Salary.component.ts File
The salary component would be responsible to display the salary details like Employee base + bonus = total salary. The salary component will have salary as the Input property.
Open and Edit Salary.component.html File
Displays the salary in table format.
salary.component.html:
Open and Edit Employee.component.ts File
The employee component will also expect an employee object as an Input.
employee.component.ts:
Open and Edit Employee.component.html File
This component is responsible for displaying employee details along with the embedded salary component. Hence you would see that we have used the app-salary component. [salary]=employee. salary used to pass salary to the SalaryComponent.
employee.component.html:
Open and Edit App Component
AppComponent will pass the employee object to EmployeeComponent.
app.component.html:
app.component.ts:
Output:
Open and Edit Employee.component.ts File Again
Next, we will add the Update button on the Employee component. We will try to call the updateSalary method of SalaryComponent.
employee.component.ts:
Output:
Using ViewChildren with ChildComponents
Suppose now we want to render multiple employees retrieved from the employees array. We can do that using the *ngFor loop rendering the employee component inside. Query multiple elements with Child Components
app.component.html:
You can query to get all EmployeeComponent(child) components from the AppComponent(parent) component. @ViewChildren decorator can be used here, pass {read: EmployeeComponent} to let the change detector query the EmployeeComponent token.
Usage of QueryList
What is QueryList?
- QueryList is an iterable collection of items
- Provides an easy API to deal with the collection of views
- ViewChildren / ContentChildren returns the QueryList<Type> result.
API:
Property | Datatype |
---|---|
dirty | boolean |
first | number |
last | number |
length | number |
changes | Observable<T> |
changes:
Returns an Observable of QueryList notifying the subscribers of changes.
Syntax:
Any changes trigger a subscription. You can access the properties mentioned above in the API section.
Output in a browser console:
Conclusion
- We have understood how to use @ViewChild and @ViewChildren
- How can we access public properties/methods from the parent component using ViewChild
- ViewChildren's QueryList can be used when multiple views have to be observed.