Angular将多个模板传递给组件
Posted
技术标签:
【中文标题】Angular将多个模板传递给组件【英文标题】:Angular pass multiple templates to Component 【发布时间】:2017-09-23 17:10:54 【问题描述】:我正在尝试创建一个接受多个模板作为输入的组件。这是我的例子:
@Component(
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<ng-template
*ngFor="let item of itemsData"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="itemTemplate"
></ng-template>
`
)
export class DataListComponent
@Input() itemsData: any[];
@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
如您所见,这是我正在尝试的一个相当简单的组件。该组件仅接受要显示的项目的数据以及项目的模板。这个组件可以这样使用:
<data-list [itemsData]="data">
<ng-template let-item>
<h1> item.header </h1>
<div> item.content </div>
</ng-template>
</data-list>
如上所示,我使用ng-content
传递模板,然后由DataListComponent
和@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
读取。
我的问题是是否可以将多个模板传递给一个组件。
作为示例,我们会传递项目的模板,但如果它是第一个项目,则需要不同的模板。这意味着将在DataListComponent
中对第一项进行检查,然后使用由使用它的组件指定的模板。
简单示例:
我可以这样做来解决这个问题:
@Component(
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<span *ngFor="let item of itemsData; let i = index" >
<ng-template *ngIf="i > 0; else nextTmpl"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="itemTemplate"
></ng-template>
</span>
<ng-template #nextTmpl>
Next
</ng-template>
`
)
然而,“下一个模板”不是由使用DataListComponent
的组件指定的,因此将始终是相同的模板。
【问题讨论】:
您的意思是ngIf
?
是的,我已经更新了问题,试图更好地解释我的意思。
如果您希望在“外部”上命名您的模板,这是一个更好的方法***.com/a/66172026/16940
【参考方案1】:
试试这个吧。
@Component(
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<ng-template ngFor [ngForOf]="itemsData" [ngForTemplate]="itemTemplate"></ng-template>
`
)
export class DataListComponent
@Input() itemsData: any[];
@ContentChild(TemplateRef) itemTemplate: TemplateRef<ElementRef>;
【讨论】:
【参考方案2】:我通过使用 ContentChild 装饰器可用的字符串选择器解决了同样的问题。
使用数据列表组件时需要指定模板变量:
<data-list [itemsData]="data">
<ng-template #firstItemTemplate let-item>
<h1 style="color:red;"> item.header </h1>
<div> item.content </div>
</ng-template>
<ng-template #standardTemplate let-item>
<h1> item.header </h1>
<div> item.content </div>
</ng-template>
</data-list>
然后,在您的数据列表组件类中,将模板变量分配给组件上的局部变量:
@Input() itemsData: any[];
@ContentChild('firstItemTemplate') firstItemTemplate: TemplateRef<ElementRef>;
@ContentChild('standardTemplate') standardTemplate: TemplateRef<ElementRef>;
在此之后,您将能够从数据列表组件呈现传入的模板。
@Component(
selector: 'data-list',
styles: [
require('./data-list.component.scss')
],
template: `
<span *ngFor="let item of itemsData; let i = index" >
<ng-template *ngIf="i == 0; else nextTmpl"
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="firstItemTemplate"
></ng-template>
<ng-template #nextTmpl
ngFor let-item [ngForOf]="[item]" [ngForTemplate]="standardTemplate"
></ng-template>
</span>
`
)
【讨论】:
这是一种聪明的做法!看起来很整洁 :) 我一定会试一试,然后告诉你进展如何。 这很好,谢谢。我唯一需要添加的是*ngIf="i > 0"
#nextTmpl
我知道这有点奇怪,但在下一个模板中我得到了两个模板。
你如何传递索引?
@Wei-jye 要传递索引,我建议将data-list
组件模板更改为使用<ng-container *ngTemplateOutlet="standardTemplate; context: item: item, index: i "></ng-container>
而不是当前的<ng-template ngFor...
方法。可能值得提出一个新问题,具体取决于您要完成的所有工作。以上是关于Angular将多个模板传递给组件的主要内容,如果未能解决你的问题,请参考以下文章
将 AngularJS 数组传递给降级的 Angular 7 组件
如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件
将 Angular Reactive FormControls 传递给子组件