Skip to main content
Практика завдань

ViewChild та ContentChild в Angular

ViewChild та ContentChild

@ViewChild та @ContentChild — це декоратори, які надають вам програмний доступ до дочірніх елементів, компонентів або директив у вашому шаблоні.


@ViewChild — Доступ до елементів шаблону

Доступ до елементів, визначених у власному шаблоні компонента:

typescript
@Component({ template: \` <input #nameInput type="text"> <app-chart #chart [data]="chartData"></app-chart> <button (click)="focusInput()">Фокус</button> \` }) export class MyComponent implements AfterViewInit { @ViewChild('nameInput') inputEl!: ElementRef<HTMLInputElement>; @ViewChild('chart') chartComponent!: ChartComponent; ngAfterViewInit() { // Доступно після ініціалізації виду this.inputEl.nativeElement.focus(); this.chartComponent.refresh(); } focusInput() { this.inputEl.nativeElement.focus(); } }

@ViewChildren — Багато елементів

typescript
@Component({ template: \` <app-tab *ngFor="let tab of tabs" [title]="tab.title"> {{ tab.content }} </app-tab> \` }) export class TabsComponent implements AfterViewInit { @ViewChildren(TabComponent) tabComponents!: QueryList<TabComponent>; ngAfterViewInit() { this.tabComponents.forEach(tab => console.log(tab.title)); // Реакція на зміни (коли *ngFor додає/видаляє елементи) this.tabComponents.changes.subscribe(tabs => { console.log('Вкладки змінено:', tabs.length); }); } }

@ContentChild — Доступ до проекційного контенту

Доступ до елементів, проектованих у компонент через <ng-content>:

typescript
@Component({ selector: 'app-panel', template: \` <div class="panel"> <ng-content></ng-content> </div> \` }) export class PanelComponent implements AfterContentInit { @ContentChild('panelTitle') titleEl!: ElementRef; @ContentChild(ButtonComponent) button!: ButtonComponent; ngAfterContentInit() { // Доступно після ініціалізації контенту console.log(this.titleEl?.nativeElement.textContent); } }
html
<!-- Шаблон батька --> <app-panel> <h2 #panelTitle>Моя панель</h2> <app-button>Натисніть на мене</app-button> </app-panel>

ViewChild проти ContentChild

Особливість@ViewChild@ContentChild
Доступає доВласного шаблону компонентаПроектованого контенту (ng-content)
Життєвий циклngAfterViewInitngAfterContentInit
Багато@ViewChildren@ContentChildren
Визначено вШаблоні компонентаШаблоні батька (проектований)

Запити сигналів (Angular 17+)

typescript
@Component({ /* ... */ }) export class MyComponent { // Запити на основі сигналів (сучасні) nameInput = viewChild.required<ElementRef>('nameInput'); chart = viewChild(ChartComponent); tabs = viewChildren(TabComponent); // Запити контенту title = contentChild<ElementRef>('title'); buttons = contentChildren(ButtonComponent); }

Опція Read

typescript
// Читати як ElementRef замість екземпляра компонента @ViewChild('myComp', { read: ElementRef }) el!: ElementRef; // Читати ViewContainerRef (для динамічних компонентів) @ViewChild('container', { read: ViewContainerRef }) container!: ViewContainerRef;

Важливо:

@ViewChild отримує доступ до елементів у власному шаблоні компонента (доступно в ngAfterViewInit). @ContentChild отримує доступ до проектованого контенту (доступно в ngAfterContentInit). В Angular 17+ віддавайте перевагу запитам на основі сигналів (viewChild(), contentChild()). Використовуйте QueryList.changes, щоб реагувати на зміни динамічного контенту.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань