@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.