Angular 角度2+;使用ngTemplateOutlet
我将尝试遵循本教程: 但是如果我复制代码,它就不起作用了。它显示:Angular 角度2+;使用ngTemplateOutlet,angular,typescript,Angular,Typescript,我将尝试遵循本教程: 但是如果我复制代码,它就不起作用了。它显示: <ul> <li></li> </ul> 编辑:以前的plnkr不正确。忘了保存。看看这个: 从'@angular/core'导入{Directive}; 从'@angular/core'导入{Component,ContentChild,Input,TemplateRef}; @指示({ 选择器:“[cardItem]” }) 导出类指令{} @指示({ 选择器:“[lis
<ul>
<li></li>
</ul>
编辑:以前的plnkr不正确。忘了保存。看看这个:
从'@angular/core'导入{Directive};
从'@angular/core'导入{Component,ContentChild,Input,TemplateRef};
@指示({
选择器:“[cardItem]”
})
导出类指令{}
@指示({
选择器:“[listItem]”
})
导出类ListItemDirective{}
@组成部分({
选择器:“卡片或列表视图”,
模板:`
-
`
})
导出类CardOrListViewComponent{
@输入()项:任意[]=[];
@输入()模式:“卡片”|“列表”=“卡片”;
//以TemplateRefs的形式阅读我们的结构指令
@ContentChild(CardItemDirective,{read:TemplateRef})cardItemTemplate;
@ContentChild(ListItemDirective,{read:TemplateRef})listItemTemplate;
}
@组成部分({
选择器:“应用程序使用情况”,
模板:`
静态卡片模板
静态列表模板
`
})
导出类UsageExample{
模式='列表';
项目=[
{
标题:“在Angular中使用NgTemplateOutlet创建可重用组件”,
内容:“单一责任原则……”
}//…更多项目
];
}
您是对的,ContentChildren总是未定义的,因为它们从未被定义过。ngTemplateOutlet将templateRef或组件作为参数,因为您的内容子级从不呈现,所以在代码中的任何位置都不会定义该参数。我个人更喜欢查看ContainerRef/ComponentFactoryResolver路由:
这使您能够更精确地控制组件,并允许您通过编程设置@Input变量。希望这有帮助您是对的,ContentChildren总是未定义的,因为它们从未被定义过。ngTemplateOutlet将templateRef或组件作为参数,因为您的内容子级从不呈现,所以在代码中的任何位置都不会定义该参数。我个人更喜欢查看ContainerRef/ComponentFactoryResolver路由:
这使您能够更精确地控制组件,并允许您通过编程设置@Input变量。希望这对您有所帮助您必须将模板放入
中,或者使用,以便您可以将其与:
静态列表模板
或更短:
<li *listItem>
Static List Template
</li>
静态列表模板
注意:您将有两个嵌套的
li
标记。也许不是你想要的 您必须将模板放在
中,或使用,以便可以将其与:
静态列表模板
或更短:
<li *listItem>
Static List Template
</li>
静态列表模板
注意:您将有两个嵌套的
li
标记。也许不是你想要的 您提供的plunker似乎与问题无关。链接错误?抱歉,忘记保存。用new linkHey@UrbKr编辑了我的帖子,我是该教程的作者。事实上有一个打字错误。静态模板应该有一个星号,因为您只能通过两种方式访问TemplateRef
。没有它,ContentChild
将是未定义的。我会尽快更新教程。Cheers@MarkKennedy好的,太好了!也许这不是一个合适的提问地点,但是你对你在教程中概述的模式和这里描述的模式有什么想法吗:你认为它有不同的用途吗?你提供的plunker似乎与这个问题无关。链接错误?抱歉,忘记保存。用new linkHey@UrbKr编辑了我的帖子,我是该教程的作者。事实上有一个打字错误。静态模板应该有一个星号,因为您只能通过两种方式访问TemplateRef
。没有它,ContentChild
将是未定义的。我会尽快更新教程。Cheers@MarkKennedy好的,太好了!也许这不是一个合适的提问地点,但是你对你在教程中概述的模式和这里描述的模式有什么想法吗:你认为它有不同的用途吗?看看这个作品吧!有些东西改变了,因为教程似乎没有做任何这些事情。也许这是个错误。我认为这是教程中的一个小错误。如果你遵循它的其余部分,那么他们会在后面添加星号。看看这个效果如何!有些东西改变了,因为教程似乎没有做任何这些事情。也许这是个错误。我认为这是教程中的一个小错误。如果您按照它的其余部分,那么他们将在稍后添加星号。谢谢!我接受了另一个答案,因为它直接修复了代码。尽管如此,我还是会检查替代方案。您是否在所有情况下都使用此方法?是的,只是因为我创建了一个可重复使用的指令,所以使用ngTemplate路线不会为我节省任何额外的工作。谢谢!我接受了另一个答案,因为它直接修复了代码。尽管如此,我还是会检查替代方案。您是否在所有情况下都使用此方法?是的,只是因为我创建了一个可重用的指令,我可以使用它,所以使用ngTemplate路由不会为我节省任何额外的工作。
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
];
}
<ng-template listItem>
<li>
Static List Template
</li>
</ng-template>
<li *listItem>
Static List Template
</li>