Что такое ViewChild

Ответ

ViewChild — это декоратор в Angular, который позволяет получить доступ к дочернему компоненту, директиве или DOM-элементу из родительского компонента.

Пример:

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    <div #myDiv>Some content</div>
    <app-child></app-child>
  `
})
export class ParentComponent {
  @ViewChild('myDiv') divRef: ElementRef;
  @ViewChild(ChildComponent) child: ChildComponent;

  ngAfterViewInit() {
    console.log(this.divRef.nativeElement.textContent); // Доступ к DOM
    this.child.someMethod(); // Вызов метода дочернего компонента
  }
}

Особенности:

  • Работает только после ngAfterViewInit.
  • Можно использовать с шаблонными переменными (#myDiv) или классами компонентов/директив.
  • Для нескольких элементов используется @ViewChildren.

Ответ 18+ 🔞

Слушай, ну вот есть у тебя этот Angular, да? И сидишь ты такой, пишешь компонент, а внутри него ещё один компонент сидит, как сыч в дупле. И тебе вдруг позарез надо из родительского компонента к этому внутреннему достучаться. Ну, например, крикнуть ему: «Эй, сынок, выполни-ка метод someMethod()!» Или в DOM-элемент ткнуть пальцем, текст прочитать.

Так вот, для этого гениального дела есть декоратор @ViewChild. Это как волшебная палочка, только для кода. Объясняю на пальцах, без этой вашей зауми.

Смотри, как это выглядит в деле:

import { Component, ViewChild, ElementRef } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    <div #myDiv>Какой-то там контент</div> <!-- Вот на этот див глаз положил -->
    <app-child></app-child> <!-- А тут целый дочерний компонент притулился -->
  `
})
export class ParentComponent {
  @ViewChild('myDiv') divRef: ElementRef; // Ловим див по метке #myDiv
  @ViewChild(ChildComponent) child: ChildComponent; // Ловим дочерний компонент по типу

  ngAfterViewInit() {
    // Всё, вид отрисовался, можно шашлыки доставать
    console.log(this.divRef.nativeElement.textContent); // Легко читаем, что в диве написано
    this.child.someMethod(); // А тут командуем дочерним компонентом: «Работай, сука!»
  }
}

А теперь главные фишки, без которых нихуя не получится:

  • Не торопи события! @ViewChild начинает работать только после хука ngAfterViewInit(). До этого там undefined, пустота, вакуум. Это как пытаться позвать сына, который ещё не родился — только матюки в пустоту посылать.
  • Ловить можно по-разному: либо по шаблонной переменной (это эта #myDiv), либо прямо по классу компонента или директивы. Удобно, ёпта.
  • Если их несколько, этих элементов? Тогда твой выход — @ViewChildren. Это уже не одинокий снайпер, а очередь из автомата.