@ViewChildren — это декоратор в Angular, который позволяет получить доступ к нескольким дочерним элементам или директивам текущего компонента. В отличие от @ViewChild, который работает с одним элементом, @ViewChildren возвращает QueryList — специальную коллекцию элементов, которая может обновляться динамически.
import { Component, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-parent',
template: `
<app-child></app-child>
<app-child></app-child>
`
})
export class ParentComponent {
@ViewChildren(ChildComponent) children: QueryList<ChildComponent>;
}
@Component({
template: `
<div #item>Item 1</div>
<div #item>Item 2</div>
`
})
export class MyComponent {
@ViewChildren('item') items: QueryList<ElementRef>;
}
@Directive({ selector: '[myDirective]' })
export class MyDirective {}
@Component({
template: `
<div myDirective></div>
<div myDirective></div>
`
})
export class MyComponent {
@ViewChildren(MyDirective) directives: QueryList<MyDirective>;
}
Динамическое обновление
QueryList автоматически обновляется при изменении DOM (добавлении/удалении элементов).
Методы и свойства:
length — количество элементовfirst — первый элементlast — последний элементchanges — Observable для отслеживания измененийforEach() — итерация по элементамtoArray() — преобразование в массивngAfterViewInit() {
console.log(this.items.length); // Количество элементов
this.items.changes.subscribe(() => {
console.log('Коллекция изменилась');
});
}
Доступ к элементам возможен только после хука ngAfterViewInit. Попытка доступа раньше (например, в ngOnInit) приведет к пустой коллекции.
@ViewChildren('input') inputs: QueryList<ElementRef>;
setFocusToNext() {
const inputsArray = this.inputs.toArray();
const activeIndex = inputsArray.findIndex(i => i.nativeElement === document.activeElement);
if (activeIndex < inputsArray.length - 1) {
inputsArray[activeIndex + 1].nativeElement.focus();
}
}
@ViewChildren(ChildComponent) children: QueryList<ChildComponent>;
disableAllChildren() {
this.children.forEach(child => child.disable());
}
@ViewChildren('item') items: QueryList<ElementRef>;
ngAfterViewInit() {
this.items.changes.subscribe(items => {
console.log(`Количество элементов изменилось: ${items.length}`);
});
}
Важно не путать @ViewChildren с @ContentChildren:
@ViewChildren — для элементов, которые являются частью шаблона компонента@ContentChildren — для проекцированного контента (ng-content) @ViewChildren используется для получения доступа к коллекции дочерних элементов, компонентов или директив, объявленных в шаблоне текущего компонента. Это мощный инструмент для взаимодействия с динамическими коллекциями элементов, с автоматическим отслеживанием изменений в DOM через QueryList.