我有一个List
组件,用于呈现列表。 (嗯,我没有,但是我试图将我的问题分解成一个易于理解的点头例子)。
List
组件的模板具有一个或多个ListItem
组件,这些组件允许定义列表项,如下所示:
<app-list>
<app-list-item text='foo'></app-list-item>
<app-list-item text='bar'></app-list-item>
</app-list>
...应呈现为:
- foo
- 酒吧
我也有一个Reminder
组件,它使用List
组件。 Reminder
组件具有deadline
属性,并且使用我们之前看到的一个或多个ListItem
组件,在该截止日期之前要做的事情清单是在该组件的模板中定义的:< / p>
<app-reminder deadline='Today'>
<app-list-item text='foo'></app-list-item>
<app-list-item text='bar'></app-list-item>
</app-reminder>
这应该呈现为:
请记住在今天之前执行以下操作:
- foo
- 酒吧
List
组件非常简单:
@Component({
selector: 'app-list',
template: `
<ul>
<ng-content></ng-content>
</ul>
`
})
export class ListComponent{
@ContentChildren(ListItemComponent) public readonly items: QueryList<ListItemComponent>;
}
ListItem
组件更简单:
@Component({
selector: 'app-list-item',
template: '<li>{{text}}</li>'
})
export class ListItemComponent {
@Input() public text;
}
最后,Reminder
组件也非常简单:
@Component({
selector: 'app-reminder',
template: `
<h2>Remeber to do the following by {{deadline}}</h2>
<app-list>
<ng-content></ng-content>
</app-list>
`
})
export class ReminderComponent {
@Input() public deadline: string;
}
将这些组件与上面显示的模板片段一起使用可以正常工作。您可以在this StackBlitz中看到这一点。
现在是问题的重点。 List
组件和Reminder
组件都使用<ng-content>
。在这两种情况下,我们实际上都不希望将所有内容投影到列表中,而只是将<app-list-item>
元素投影到列表中。
如果我像这样更改<ng-content>
组件模板中的Reminder
标签:
<ng-content select='app-list-item'></ng-content>
...然后,该组件仍然可以工作,并且在模板中排除了我们想要的任何其他内容。
如果我对<ng-content>
组件的模板中的List
标签进行了相同的更改,那么这也适用于像这样的简单模板:
<app-list>
<app-list-item text='foo'></app-list-item>
<app-list-item text='bar'></app-list-item>
<h1>EXCLUDE ME</h1>
</app-list>
但是,最后一次更改(向select
组件模板中的<ng-content>
元素添加List
过滤器)停止了Reminder
组件从工作。提醒中没有呈现任何列表项。
我想这可能是因为List
组件的模板所呈现的Reminder
组件看到的是 rendered 内容(<li>
标签),而不是 template 内容(<app-list-item>
标签)。
似乎我在这里有一个不愉快的选择-我可以不限制List
组件将呈现的内容类型(在这种情况下,任何旧的垃圾可能会包括在内),或者在创建其他组件时失去使用List
组件的功能。
还是我错过了什么?还有另一种方法吗?
答案 0 :(得分:2)
我设法使用ngProjectAs解决了这个问题。
@Component({
selector: 'app-reminder',
template: `
<h2>Remeber to do the following by {{deadline}}</h2>
<app-list>
<ng-container ngProjectAs="'app-list-item'">
<ng-content select='app-list-item'></ng-content>
</ng-container>
</app-list>
`
})
export class ReminderComponent {
@Input() public deadline: string;
}