Reputation: 1281
Using Angular 4.0.3
I'm trying to create a component to display an array as a list. I need to have the option of passing a template to this component. If a template is passed, the list will be rendered using it. Otherwise, an embedded template should be used to render.
I've found a Plunkr that partially solves what I'm trying to do - it shows how to pass a template to a component, and have the component render using it. It can be found here: https://embed.plnkr.co/ollxzUhka77wIXrJGA9t/
I've forked it and tried adding the default template functionality required. To do this, I've:
In src/app.ts
:
dynamic-list
component with no template (lines 29-30)In src/dynamic-list.component.ts
:
ngForTemplate
reference to use itemTemplate
if it exists, else falling back to defaultItemTemplate
(line 4)defaultItemTemplate
, using @ViewChild(TemplateRef)
to get a reference to the embedded default templateThat plunkr can be found at https://embed.plnkr.co/QtMk3h/
When running, I'm getting this exception:
Error in ./DynamicListComponent class DynamicListComponent - inline template:0:29
I'm not sure what I'm doing wrong, as setting *ngForTemplate="itemTemplate"
works, but neither *ngForTemplate="defaultItemTemplate"
or *ngForTemplate="itemTemplate || defaultItemTemplate"
don't.
What am I doing wrong?
I also notice that *ngFor
is deprecated, so maybe I'm approaching this in the wrong way now?
Upvotes: 2
Views: 1538
Reputation: 17859
I rewrite this plnkr using Angular4 + added else clause.
https://plnkr.co/edit/i3czMfuziB9eWkiepEW0?p=preview
@Component({
selector: 'dynamic-list',
template: `<div *ngFor="let item of items">
<ng-container *ngIf="itemTemplate;else elseBlock">
<ng-container *ngTemplateOutlet="itemTemplate; context: {\$implicit:item}"></ng-container>
</ng-container>
</div>
<ng-template #elseBlock>else</ng-template>
`
})
export class DynamicListComponent {
@ContentChild(TemplateRef)
public itemTemplate: TemplateRef;
@Input()
public items: number[];
ngAfterContentInit() {
console.log(this.itemTemplate);
}
}
@Component({
selector: 'dynamic-list-item',
template: `<div>
Template Item #:{{item}}
</div>`
})
export class DynamicListItemTemplateComponent {
@Input() public item: number;
}
@Component({
selector: 'my-app',
providers: [],
template:`
<h3>Inline</h3>
<h3>Default</h3>
<dynamic-list [items]="items">
</dynamic-list>
<h3>Not Default</h3>
<div *ngFor="let item of items">
<div>
Inline template item #: {{item}}
</div>
</div>
<h3>List component with inline template</h3>
<dynamic-list [items]="items">
<ng-template let-item>
Inline template item #: {{item}}
</ng-template>
</dynamic-list>
<h3>List component with component template</h3>
<dynamic-list [items]="items">
<dynamic-list-item template="let item" [item]="item"></dynamic-list-item>
</dynamic-list>
`,
})
export class App {
private items = [1, 2, 3, 4];
}
Upvotes: 2