Не удается заставить ngTemplateOutlet работать
Я пытаюсь создать компонент списка в Angular2, который берет элементы, столбцы и шаблоны для полей элементов от пользователя компонента. Поэтому я пытаюсь использовать ngTemplateOutlet
и ngOutletContext
(которые я прочитал, являются экспериментальными). Но я не могу заставить его работать.
Вот упрощенный компонент, демонстрирующий, что я пытаюсь сделать:
<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
Вот как вам нужно это сделать:
@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
обновление Angular 5
ngOutletContext
было переименовано в ngTemplateOutletContext
См. также https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
оригинальный
Не используйте []
и {{}}
вместе. Либо тот, либо другой, но не оба.
Не используйте {{}}
, если вы хотите передать объект, потому что {{}}
используется для строковой интерполяции.
Это должно быть
[ngTemplateOutlet]="column.templateRef"
Пример плунжера
Ответ 3
Вы можете сделать это без ngOutletContext. Вы должны использовать NG-шаблон вместо шаблона.
у меня работает следующий код:
app.component.html:
<div>
<ng-template #c1>
<app-child1></app-child1>
</ng-template>
<app-parent [templateChild1]="c1"></app-parent>
</div>
app-parent - это дочерний элемент приложения-компонента. app-child объявлен в app-component как шаблон, и этот шаблон используется в app-parent.
app.parent.html:
<p>
<ng-template [ngTemplateOutlet]="templateChild1"></ng-template>
</p>
app.parent.ts:
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
@Input() public templateChild1: TemplateRef<any>;
public ngOnInit() {
}
}