Я начну с использования моего компонента на компоненте хостинга:
<my-templated-component [content-template]="contentTemplate">
</my-templated-component>
<ng-template #contentTemplate>
<h3>Hello There</h3>
<div>Lorem ipsum..... </div>
<custom-component></custom-component>
</ng-template>
Теперь, мой компонент .ts:
class MyTemplatedComponent implements AfterContentInit {
@Input('content-template') contentTemplate: TemplateRef<any>;
@ContentChildren(CustomComponent) customComponentQueryList: QueryList<CustomComponent>;
...
ngAfterContentInit() {
// Length is 0 at this point. My component didn't find the component I want
console.log(`There are ${this.customComponentQueryList.length} items`);
this.customComponentQueryList.changes.subscribe((s) => {
/* This is not called. This is where I would have wanted to find
my CustomComponent to perform a task that requires its presence.
*/
});
}
}
А вот разметка для MyTemplatedComponent
:
<ng-container *ngTemplateOutlet="contentTemplate">
</ng-container>
Я понимаю, что QueryList<CustomComponent>
будет доступен только на ngAfterContentInit()
.Без подписки на него CustomComponentQueryList
не имеет элементов, поэтому он не нашел CustomComponent
из @Input
ted TemplateRef
.Но changes
из QueryList<CustomComponent>
не запускается, поэтому я определенно не могу найти свой компонент.
Странно то, что я вижу все из этого @Input
ted TemplateRef
настраницы, включая разметку от CustomComponent
.Итак, MyTemplatedComponent
обнаруживает мой введенный шаблон ссылки и отображает его через *ngTemplateOutlet
, но QueryList
не может найти мой CustomComponent
?
Теперь,однако, если я изменил @Input() contentTemplate: TemplateRef<any>
на @ContentChild('contentTemplate') contentTemplate: TemplateRef<any>
, а затем поместил шаблон внутри , теги <my-templated-component>
выглядят так:
<my-templated-component>
<ng-template #contentTemplate>
<h3>Hello There</h3>
<div>Lorem ipsum..... </div>
<custom-component></custom-component>
</ng-template>
</my-templated-component>
QueryList
changes
срабатывает , и по подписке я могу найти мои CustomComponent
.
Возможно @ContentChild
и @ContentChildren
будут работать только в том случае, если Я прямо положил <ng-template>
как непосредственный дочерний элемент разметки / селектора моего компонента, как я делал выше.
Но я не всегда получу plop <my-templated-component>
таким образом, и тамбудут времена, когда <ng-template #contentTemplate>
может даже прийти извне хост-компонента.
Все хорошо, если все, что я хочу сделать, это взять TemplateRefs
и отобразить их где-нибудь в моих шаблонных компонентах, но яВам нужно будет исследовать содержимое из TemplateRefs
, которое я получу для различных целей.
Если @ContentChildren
требует, чтобы япоместите мои <ng-template>
в теги моего компонента, что будет эквивалентным декоратором (я не думаю, что он есть, и это определенно не @ViewChildren
), если TemplateRef
был передан через @Input
?Есть ли эффективные обходные пути?
В конечном счете, изнутри шаблонных компонентов, как мы находим определенные компоненты внутри TemplateRef
, передаваемые как @Input
, если @ContentChildren
QueryList<T>
не работают?