Loading...

ViewChildren()in Angular

ViewChildren() is a decorator in Angular that allows you to access a list of child components, directives, or DOM elements from a parent component's class. It provides a way to interact with multiple matching elements defined in the template from the component's TypeScript code.

ViewChildren() allows you to query the template for all elements that match a given selector. This selector can be a component, directive, or template reference variable. Unlike ViewChild(), which returns a single element, ViewChildren() returns a QueryList containing all matching elements.

Why Use ViewChildren()?

  • Multiple Component Interaction: Allows you to interact with multiple child component instances.
  • Multiple Directive Interaction: Enables you to interact with multiple directives applied to elements.
  • Multiple DOM Element Manipulation: Facilitates direct manipulation of multiple DOM elements.

Using ViewChildren()

To use ViewChildren(), you need to import it from @angular/core and use it as a decorator on a property in your component class. The property will be of type QueryList.

Example 1: Accessing Multiple Child Components

In this example, we'll access multiple child components and call their methods.

Child Component (child.component.ts)


    import { Component } from '@angular/core';

    @Component({
      selector: 'app-child',
      template: '<p>Child Component</p>'
    })
    export class ChildComponent {
      showMessage(index: number): void {
        alert('Hello from ChildComponent ${index}!');
      }
    }
    

Parent Component (parent.component.ts)


    import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
    import { ChildComponent } from './child.component';

    @Component({
      selector: 'app-parent',
      template: '<app-child></app-child><app-child></app-child><app-child></app-child><button (click)="callChildrenMethods()">Call Children Methods</button>'
    })
    export class ParentComponent implements AfterViewInit {
      @ViewChildren(ChildComponent) childComponents: QueryList<ChildComponent>;

      ngAfterViewInit(): void {
        console.log('Child Components:', this.childComponents);
      }

      callChildrenMethods(): void {
        this.childComponents.forEach((child, index) => {
          child.showMessage(index + 1);
        });
      }
    }
    

Explanation:

  • @ViewChildren(ChildComponent) childComponents: QueryList<ChildComponent>;: Decorates the childComponents property with ViewChildren(), specifying the ChildComponent as the selector.
  • ngAfterViewInit(): Lifecycle hook that runs after the component's view has been initialized.
  • callChildrenMethods(): Iterates through the QueryList and calls the showMessage() method of each ChildComponent instance.

Example 2: Accessing Multiple Directives

In this example, we'll access multiple directives and use their properties.

Directive (highlight.directive.ts)


    import { Directive, ElementRef, HostListener } from '@angular/core';

    @Directive({
      selector: '[appHighlight]'
    })
    export class HighlightDirective {
      constructor(private el: ElementRef) {}

      @HostListener('mouseenter') onMouseEnter() {
        this.highlight('yellow');
      }

      @HostListener('mouseleave') onMouseLeave() {
        this.highlight(null);
      }

      private highlight(color: string) {
        this.el.nativeElement.style.backgroundColor = color;
      }
    }
    

Parent Component (parent.component.ts)


    import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
    import { HighlightDirective } from './highlight.directive';

    @Component({
      selector: 'app-parent',
      template: '
        <p appHighlight>Highlight 1</p>
        <p appHighlight>Highlight 2</p>
        <p appHighlight>Highlight 3</p>
        <button (click)="changeHighlights()">Change Highlights</button>
      '
    })
    export class ParentComponent implements AfterViewInit {
      @ViewChildren(HighlightDirective) highlightDirectives: QueryList<HighlightDirective>;

      ngAfterViewInit(): void {
        console.log('Highlight Directives:', this.highlightDirectives);
      }

      changeHighlights(): void {
        this.highlightDirectives.forEach(directive => {
          directive['highlight']('lightblue');
        });
      }
    }
    

Explanation:

  • @ViewChildren(HighlightDirective) highlightDirectives: QueryList<HighlightDirective>;: Decorates the highlightDirectives property with ViewChildren(), specifying the HighlightDirective as the selector.
  • ngAfterViewInit(): Lifecycle hook that runs after the component's view has been initialized.
  • changeHighlights(): Iterates through the QueryList and calls the highlight() method of each HighlightDirective instance.

Key Points

  • ViewChildren() allows access to multiple child components, directives, and DOM elements.
  • Use it in combination with the AfterViewInit lifecycle hook.
  • It simplifies interactions with multiple elements defined in the template.
  • Use QueryList to hold the list of elements.

If you have any questions, feel free to ask. Thank you for reading!

Thankyou!