@ContentChildren
и QueryList
— это мощные инструменты Angular для работы с проекцией контента (content projection) и динамическими дочерними элементами. Они позволяют компоненту взаимодействовать с элементами, которые передаются в его слот <ng-content>
.
@ContentChildren
— это декоратор, который выполняет запрос к проекционному контенту компонента.
<ng-content>
)QueryList
— специальную коллекцию Angular@ContentChildren(selector, options?) propertyName: QueryList<T>;
TemplateRef
ViewContainerRef
descendants: boolean
- включать ли потомковread: any
- получить конкретный тип (например, ViewContainerRef)QueryList
— это специальная коллекция Angular, которая:
@ContentChildren
changes
— Observable для отслеживания измененийinterface QueryList<T> {
length: number;
first: T;
last: T;
get(index: number): T;
forEach(fn: (item: T, index: number) => void): void;
map<U>(fn: (item: T, index: number) => U): U[];
filter(fn: (item: T, index: number) => boolean): T[];
find(fn: (item: T, index: number) => boolean): T|undefined;
reduce<U>(fn: (prevValue: U, curValue: T, curIndex: number) => U, init: U): U;
some(fn: (value: T, index: number) => boolean): boolean;
toArray(): T[];
changes: Observable<any>;
}
@Component({
selector: 'app-tab-group',
template: `
<div class="tab-header">
<ng-content select="app-tab-header"></ng-content>
</div>
<div class="tab-content">
<ng-content select="app-tab-content"></ng-content>
</div>
`
})
export class TabGroupComponent implements AfterContentInit {
@ContentChildren(TabHeaderComponent) headers: QueryList<TabHeaderComponent>;
@ContentChildren(TabContentComponent) contents: QueryList<TabContentComponent>;
ngAfterContentInit() {
// Синхронизация заголовков и содержимого вкладок
this.headers.forEach((header, index) => {
header.click.subscribe(() => this.activateTab(index));
});
}
activateTab(index: number) {
this.contents.forEach((content, i) => content.isActive = i === index);
}
}
@Component({
selector: 'app-list',
template: `<ng-content></ng-content>`
})
export class ListComponent implements AfterContentInit {
@ContentChildren(ListItemDirective) items: QueryList<ListItemDirective>;
ngAfterContentInit() {
this.items.changes.subscribe(() => {
console.log('Количество элементов изменилось:', this.items.length);
});
}
}
@Component({
selector: 'app-example',
template: `
<ng-content></ng-content>
<ng-content select=".special"></ng-content>
`
})
export class ExampleComponent {
// Запрос по типу директивы
@ContentChildren(HighlightDirective) highlights: QueryList<HighlightDirective>;
// Запрос по CSS-селектору
@ContentChildren('.special') specialItems: QueryList<ElementRef>;
// Получение ViewContainerRef
@ContentChildren(TemplateRef, {read: ViewContainerRef}) templates: QueryList<ViewContainerRef>;
}
ngAfterContentInit
для начального доступа к QueryListread
параметр для точного указания типа@ContentChildren
используется для запроса проекционного контентаQueryList
предоставляет динамическую коллекцию элементовngAfterContentInit
changes
ObservableЭти инструменты особенно полезны при создании библиотек компонентов и сложных динамических интерфейсов.