Let's say I got an interface (or an actual component) ListItemRenderer
and a component MyRendererComponent
that implements that interface (or extends the base component)
@Component({
selector: 'my-renderer',
template: '<div>My renderer</div>'
})
export class MyRendererComponent implements ListItemRenderer {
...
}
I'd like to pass this concrete implementation to another component, e.g.
@Component({
selector: 'my-list',
template: `
<ul [renderer]="renderer" [items]="items">
<li *ngFor="let item of items">
<!-- what goes here? -->
</li>
</ul>
`
})
export class MyList {
@Input() renderer: ListItemRenderer;
@Input() items: any[];
...
}
Obviously, the parent component would have a public property renderer
of type ListItemRenderer
. The question is, how do I go about using that component in my <li>
(see "what goes here?" above)?
To add components dynamically using
*ngFor
you need something like thedcl-wrapper
explained in https://stackoverflow.com/a/36325468/217408 (DynamicComponentLoader
is deprecated in favor ofViewContainerRef.createComponent()
but I didn't try to introduce another name for the wrapper component.)and use it like
The answer from Günter Zöchbauer is spot-on, here's a more complete code sample in case anybody else should encounter this problem (Angular2 RC1).
app.component.ts
renderer.ts
dynamic-list.component.ts
one-renderer.component.ts
two-renderer.component.ts
dcl-wrapper.component.ts
Here's what the resulting DOM looks like:
If you need to pass a parameter, you'll have to pass it to
DclWrapperComponent
like so:dcl-wrapper.component.ts
Here's an example implementation:
to-uppercase-renderer.component.ts
Of course, the parameter should be declared on the base component as well,
renderer.ts
You can then pass this parameter in your template as follows:
dynamic-list.component.ts