Первый , Угловые структурные директивы имеют две формы, которые мы можем использовать:
1) версия с сахаром
<div *ngIf="foo">bar</div>
2) версия без сахара
<ng-template [ngIf]="foo">
<div>bar</div>
</ng-template>
Вернемся к вашему примеру:
<ng-container *cardItem="let item">
<h1>{{item.header}}</h1> sugar
<p>{{item.content}}</p>
</ng-container>
||
\/
<ng-template cardItem let-item>
<ng-container>
<h1>{{item.header}}</h1> de-sugar
<p>{{item.content}}</p>
</ng-container>
</ng-template>
Во-вторых , обычная практика - получить ссылку на что-то в шаблоне через @ViewChild
(- dren) | @ContentChild
(-dren) decorators.
Мы можем запрашивать директивы, соответствующие элементам шаблона.Angular всегда соответствует обезвоженной версии нашего шаблона.Таким образом, директива:
@Directive({
selector: '[cardItem]'
})
export class CardItemDirective {}
соответствует шаблону:
selector: '[cardItem]'
||
\/
<ng-template cardItem let-item>
Если вы не хотите, чтобы все возможные случаи касались запроса, следуйте этому ответу :
Теперь мы знаем, что с помощью запроса @ContentChild:
@ContentChild(CardItemDirective) cardItemTemplate;
мы получаем CardItemDirective
экземпляр, но мы хотим получить TemplateRef
, чтобы использовать его в *ngTemplateOutlet
.
Вот где на помощь приходит опция read :
@ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
\/
please give us TemplateRef instance from the element
that matches CardItemDirective selector
Наконец , имея TemplateRef
, мы можем отрендерить его с помощью директивы ngTemplateOutlet и передать любой контекст, который мы хотим:
<div *ngFor="let item of items">
<ng-container *ngTemplateOutlet="cardItemTemplate; context: {$implicit: item}">