我正在尝试遵循本教程:
https://alligator.io/angular/reusable-components-ngtemplateoutlet/
但是如果我复制代码,它将无法正常工作。它显示:
<ul>
<li></li>
</ul>
代替
<ul>
<li>Static List Template</li>
</ul>
这些属性仍未定义:
@ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
@ContentChild(ListItemDirective, {read: TemplateRef}) listItemTemplate;
编辑:以前的plnkr不正确。忘了保存。看到这个:
https://next.plnkr.co/edit/b9kdTXoe8ZRqnuSv?open=lib%2Fapp.ts&deferRun=1&preview
import { Directive } from '@angular/core';
import { Component, ContentChild, Input, TemplateRef } from '@angular/core';
@Directive({
selector: '[cardItem]'
})
export class CardItemDirective {}
@Directive({
selector: '[listItem]'
})
export class ListItemDirective {}
@Component({
selector: 'card-or-list-view',
template: `
<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'card'">
<ng-container *ngFor="let item of items">
<ng-container *ngTemplateOutlet="cardItemTemplate"></ng-container>
</ng-container>
</ng-container>
<ul *ngSwitchCase="'list'">
<li *ngFor="let item of items">
<ng-container *ngTemplateOutlet="listItemTemplate"></ng-container>
</li>
</ul>
</ng-container>
`
})
export class CardOrListViewComponent {
@Input() items: any[] = [];
@Input() mode: 'card' | 'list' = 'card';
// Read in our structural directives as TemplateRefs
@ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
@ContentChild(ListItemDirective, {read: TemplateRef}) listItemTemplate;
}
@Component({
selector: 'app-usage',
template: `
<card-or-list-view
[items]="items"
[mode]="mode">
<div cardItem>
Static Card Template
</div>
<li listItem>
Static List Template
</li>
</card-or-list-view>
`
})
export class UsageExample {
mode = 'list';
items = [
{
header: 'Creating Reuseable Components with NgTemplateOutlet in Angular',
content: 'The single responsibility principle...'
} // ... more items
];
}
答案 0 :(得分:3)
您必须将模板放入<ng-template>
或使用asterisk-prefix syntax,以便可以与structural directive一起使用:
<ng-template listItem>
<li>
Static List Template
</li>
</ng-template>
或更短:
<li *listItem>
Static List Template
</li>
注意:您将带有两个嵌套的li
标记。也许不是您想要的...
答案 1 :(得分:1)
您是正确的,因为永远不会定义ContentChildren,所以它们始终是未定义的。 ngTemplateOutlet将templateRef或组件作为参数,由于您的内容子级从不渲染,因此从未在代码中的任何位置定义它。我个人更喜欢使用ViewContainerRef / ComponentFactoryResolver路线:https://angular.io/guide/dynamic-component-loader
这使您可以更精细地控制组件,并可以通过编程方式设置@Input变量。希望这会有所帮助