2016-11-04 110 views
16

我正在尝试在Angular2中构建一个列表组件,该组件使用了来自组件用户的项目字段的项目,列和模板。所以我试图使用ngTemplateOutletngOutletContext(我读过的是实验性的)。但我无法让它工作。无法让ngTemplateOutlet工作

下面是一个简单的组件来证明什么,我试图做的:

<div *ngFor="let item of items> 
    <span *ngFor="let column of columns> 
    <template [ngOutletContext]="{ item: item }" 
       [ngTemplateOutlet]="column.templateRef"></template> 
    </span> 
</div> 

这里是元件的使用:

<my-component [items]="cars" [columns]="carColumns"> 
    <template #model>{{item.model}}</template> 
    <template #color>{{item.color}}</template> 
    <template #gearbox>{{item.gearbox}}</template> 
</my-component> 

这里是示例数据:

cars = [ 
    { model: "volvo", color: "blue", gearbox: "manual" }, 
    { model: "volvo", color: "yellow", gearbox: "manual" }, 
    { model: "ford", color: "blue", gearbox: "automatic" }, 
    { model: "mercedes", color: "silver", gearbox: "automatic" } 
]; 

carColumns = [ 
    { templateRef: "model" }, 
    { templateRef: "color" }, 
    { templateRef: "gearbox" } 
]; 

下面是根据Günters评论: https://plnkr.co/edit/jB6ueHyEKOjpFZjxpWEv?p=preview

+1

你是不是想通过'TemplateRef'为字符串?一种方法https://plnkr.co/edit/3yM25cUVeP4fK0cxhpXp?p=preview – yurzui

+0

另一种方式是使用'ContentChildren' https://plnkr.co/edit/2Ohj12Gax6UaK6LJ5dwD?p=preview – yurzui

+0

@yurzui有趣的。你的版本如何工作,而不是我的?不,列需要是一个对象列表,因为我像头一样传递附加信息,如果它现在应该显示或不显示。看起来你和我的朋友之间唯一的区别就是你将字段作为字符串列表传递。 – Hampus

回答

20

这是你需要如何做到这一点:

@Component({ 
    selector: 'my-component', 
    template: ` 
    <div *ngFor="let item of items"> 
     <span *ngFor="let column of columns"> 
     <template [ngTemplateOutlet]="column.ref" [ngOutletContext]="{ item: item }"></template> 
     </span> 
    </div>` 
}) 
export class MyComponent { 
    @Input() items: any[]; 
    @Input() columns: any[]; 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <my-component [items]="cars" [columns]="columns"> 
     <template #model let-item="item">{{item?.model}}</template> 
     <template #color let-item="item">{{item?.color}}</template> 
     </my-component> 
    </div>` 
}) 
export class App { 
    @ViewChild('model') model; 
    @ViewChild('color') color; 
    cars = [ 
     { model: "volvo", color: "blue" }, 
     { model: "saab", color: "yellow" }, 
     { model: "ford", color: "green" }, 
     { model: "vw", color: "orange" } 
    ]; 

    ngAfterContentInit() { 
    this.columns = [ 
     { ref: this.model }, 
     { ref: this.color ] 
    ]; 
    } 
} 

Plunker

+2

谢谢一堆。我不远处,但足以感受到我的头靠在墙上的冲动。 – Hampus

+1

我很惊讶你需要明确地说'let-item =“item”'。添加一个let解决了我遇到的类似问题。你会认为这是暗示的。 –

+0

{ref:this.color]这里不是一个括号,并且在4.0改为

12

更新角5

ngOutletContext更名为ngTemplateOutletContext

参见https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29

不要使用[]{{}}在一起。无论是一个或另一个,但不是两个。

如果您想传递一个对象,请不要使用{{}},因为{{}}用于字符串插值。

应该

[ngTemplateOutlet]="column.templateRef" 

Plunker example

+0

Ahh,使得感。但仍然没有工作。现在我得到'core.umd.js:3072原始异常:templateRef.createEmbeddedView不是函数' – Hampus

+0

请提供一个Plunker来重现。仅使用一些代码片段就很难进行调试。 –

+0

我添加了一个运动员。 – Hampus