Let\'s say I have two components: parent and child. The HTML would look like this:
For projecting content to an element (transclusion) you would need the element like
@Component({
selector: 'parent',
directives: [ChildComponent], // needed?
template: `
{{title}}
-
`
})
but that won't work for your use case because doesn't produce content, it only projects it (works as a placehoder where children are displayed within your components template.
Even though *ngFor would produce 3 elements, the children would only be displayed once in the first element.
allows to use selectors like
where a template like
-
`
would result in
Welcome
- Chris is on the Blue Team
A more flexible and powerful approach explained in Binding events when using a ngForTemplate in Angular 2 (from @kemsky s comment)
, @ViewChildren(), and *ngForTemplate
If you wrap the children in tags you can access them using @ContentChildren() and insert them using *ngFor and *ngForTemplate.
I am using a little hack here with the inner *ngFor. There is a better approach work in progress (ngTemplateOutlet https://github.com/angular/angular/pull/8021 already merged)
@Component({
selector: 'parent',
template: `
{{title}}
-
children:{{children}}
templates:{{templates}}
`
})
export class ParentComponent {
@Input() title;
@ContentChildren(TemplateRef) templates;
}
@Component({
selector: 'my-app',
directives: [ParentComponent],
template: `
Hello
Blue Team
Red Team
`,
})
export class AppComponent {}
Plunker example
See also How to repeat a piece of HTML multiple times without ngFor and without another @Component for more ngTemplateOutlet Plunker examples.
update Angular 5
ngOutletContext was renamed to ngTemplateOutletContext
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29