I'm using Angular 2-rc3 and have a Component
and I want to apply transclusion, just in a bit of a different way. Here's my component:
import { Component, Input } from '@angular/core';
@Component({
selector: 'my-list',
template: `<ul>
<li *ngFor="let item of data">
-- insert template here --
<ng-content></ng-content>
</li>
</ul>`
})
export class MyListComponent {
@Input() data: any[];
}
And I use it like this:
<my-list [data]="cars">
<div>{{item.make | uppercase}}</div>
</my-list>
As you can see, I'm trying to define an inline template that will be used by my component. Now this goes horribly wrong. First off, a databinding exception saying it can't read property 'make' of undefined
. It's trying to read item.make
off of my surrounding component, not of the MyListComponent
. But even if I temporarily disable this for now:
<my-list [data]="cars">
<div>{item.make | uppercase}</div>
</my-list>
Then the second problem appears:
-- insert template here --
-- insert template here --
-- insert template here --
-- insert template here --
{item.make | uppercase}
So Angular doesn't actually copy the template for use within the *ngFor
, it just binds the elements and they end up associated with the last item.
How do I get this to work?
I had the same issue with AngularJS, where petebacondarwin posted a solution to manipulate the DOM through compile, which was great. I have this option with Angular 2 as well by injecting ElementRef
in my component, but! One big difference is that compile
in AngularJS went off before databinding, meaning there were no problems using {{item.make}}
in the template. With Angular 2, this seems to be a no-go since {{item}}
is being parsed before-hand. So what's the best way to go about this? Using the slightly different notation [[item]]
and string replacing the entire thing doesn't seem the most elegant way...
Thanks in advance!
// Edit: Here's a Plnkr that reproduces the problem.