Open In App

Angular ViewChildren Decorator

Last Updated : 03 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The ViewChildren decorator in Angular is used to query multiple elements or directives in the view DOM and gain a reference to them. It is particularly useful when you want to interact with multiple elements of the same type or group within a template. The ViewChildren decorator returns a QueryList that provides methods to iterate, map or listen to changes in the list of queried elements.

Overview of @ViewChild and @ViewChildren

  • @ViewChild: This decorator is used to query a single element or directive within a component's view. It returns the first element that matches the selector.
  • @ViewChildren: This decorator is used to query multiple elements or directives that match the selector within a component's view. It returns a QueryList of all matching elements.

Prerequisites

Approach To Implement ViewChildren Decorator

Here are the possible approaches using the ViewChildren decorator.

Querying Native DOM Elements

This approach is sued to query multiple DOM elements within a template. The Elements are queried a template reference variable.

@ViewChildren('inputElement') inputElements: QueryList<ElementRef>;

ngAfterViewInit() {
this.inputElements.forEach(input => console.log(input.nativeElement));
}

In the template multiple DOM elements are referenced using a common template reference. The ViewChildren decorator collects all these elements and makes them accessible in the component as a QueryList of ElementRef objects.

Querying Angular Components or Directives

This approach is used when you want to query multiple instances of a child component or directive.

@ViewChildren(ChildComponent) childComponents: QueryList<ChildComponent>;

ngAfterViewInit() {
this.childComponents.forEach(component => component.someMethod());
}

This approach is helpful when you need to interact with multiple instances of a component or directive. You can call methods or access properties of the queried components or directives.

Querying Elements with a Directive Selector

This approach is similar to querying components but is specifically for querying elements that have a certain directive applied.

@ViewChildren(SomeDirective) directives: QueryList<SomeDirective>;

ngAfterViewInit() {
this.directives.forEach(directive => directive.performAction());
}

This method allows you to query all elements with a specific directive. You can then perform actions or access properties on those directives.

Understanding @ViewChild Decorator

The @ViewChild decorator is used to query a single element, component, or directive from the view. It provides direct access to the queried element or directive after the view initialization.

Metadata Properties of @ViewChild

  • selector: The element or directive to be queried.
  • read: Specifies the type to be returned

Understanding @ViewChildren Decorator

Definition and Purpose

The @ViewChildren decorator is used to query multiple elements, components, or directives within a view. It returns a QueryList of all matching elements.

Metadata Properties of @ViewChildren

  • selector: The element or directive to be queried.
  • read: Specifies the type to be returned.

Selectors Supported in View Queries

Using Component or Directive Class as Selector

You can use the class name of a component or directive to query it in the view

@ViewChild(MyComponent) myComponent: MyComponent;

Using Template Reference Variable as Selector

Template reference variables can be used to query elements.

@ViewChild('myVar') myVarElement: ElementRef;

Using Providers as Selector

You can query elements using providers as selectors when they are provided in the component's injector.

Using the read Option in View Queries

  • Reading Component or Directive Instances: You can read the instance of a component or directive by specifying the class name as the selector.
  • Reading Providers from the Injector: Providers registered in the component can be queried using the read option.
  • Reading Providers with String Tokens: Providers defined with string tokens can be queried using their string token.
  • Reading TemplateRef, ElementRef, and ViewContainerRef: The read option allows you to specify whether to return TemplateRef, ElementRef, or ViewContainerRef.

Working with QueryList and Change Detection

What is QueryList?

  • QueryList is a class used to represent a collection of items that Angular queries from the view.
  • Using QueryList with @ViewChild and @ViewChildren
  • @ViewChildren returns a QueryList, allowing you to iterate over the queried items.
  • Change Detection and QueryList#changes Observable
  • QueryList#changes is an observable that emits when the content of the QueryList changes.
  • Handling Changes with ngAfterViewInit and ngAfterViewChecked
  • Use ngAfterViewInit and ngAfterViewChecked lifecycle hooks to handle changes in the view after it is initialized.

Steps to Implement ViewChildren Decorator

Step 1 : Create a New Angular Application

Here we created a sample Angular application for ViewChildren Decorator in Angular. Follow below step by step process for your reference.

ng new view-children-example
cd view-children-example

Folder Structure

Screenshot-2024-08-21-191735
Folder Structure

Dependencies

"dependencies": {
"@angular/animations": "^18.2.0",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/forms": "^18.2.0",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/platform-server": "^18.2.0",
"@angular/router": "^18.2.0",
"@angular/ssr": "^18.2.0",
"express": "^4.18.2",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
}

Step 2 : Implement Logic For ViewChildren Decorator

Here we develop logic for ViewChildren Decorator in the Angular project. For implement this business logic we need to update the following files in the Angular project and we use Bootstrap framework for creating responsive web application.

HTML
<!-- src/index.html -->

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>ViewChildrenExample</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" 
          rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</head>

<body>
    <app-root></app-root>
</body>

</html>
HTML
<!-- src/app/app.component.html -->

<div class="container p-5 mt-5 bg-dark d-flex justify-content-center">
    <div class="row">
        <div class="col-md-4">
            <div #box class="box">Box 1</div>
        </div>
        <div class="col-md-4">
            <div #box class="box">Box 2</div>
        </div>
        <div class="col-md-4">
            <div #box class="box">Box 3</div>
        </div>
    </div>
</div>
CSS
/* src/app/app.component.css */

.box {
    width: 100px;
    height: 100px;
    margin: 10px;
    text-align: center;
    line-height: 100px;
    color: white;
    font-weight: bold;
}
JavaScript
// src/app/app.component.ts

import { Component, ElementRef, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
    selector: 'app-root',
    standalone: true,
    imports: [RouterOutlet],
    templateUrl: './app.component.html',
    styleUrl: './app.component.css'
})
export class AppComponent implements AfterViewInit {
    title = 'view-children-example';
    @ViewChildren('box') boxes!: QueryList<ElementRef>;

    ngAfterViewInit() {
        this.boxes.forEach((box, index) => {
            box.nativeElement.style.backgroundColor = this.getRandomColor();
        });
    }

    getRandomColor(): string {
        const letters = '0123456789ABCDEF';
        let color = '#';
        for (let i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
}

Step 3 : Run the Application

Once development is completed. Now Its time to run the application by using below command.

ng serve

Output

Difference between @ViewChild and @ViewChildren

Aspect

@ViewChild

@ViewChildren

Purpose

Access a single child element or components.

Access multiple child elements or components.

Returns

Single Instance

QueryList

Usage

When you need to interact with one specific item.

When you need to interact with several items.

Template Reference Variable

Used to select one item by its template reference variable.

Used to select multiple items by their template reference variable.

Common Use Cases

Accessing a single form control, input field or specific directive.

Handling list of items, multiple components or directives within a container.

When to Use @ViewChild vs. @ViewChildren

  • Use @ViewChild when you need to interact with a single element or directive.
  • Use @ViewChildren when you need to interact with multiple elements or directives.

Next Article
Article Tags :

Similar Reads