I'm pretty new in angular2 and I'm trying to make a small angular component called "grid" that simply rearranges its content using transclusion.
Its template
grid component template (grid.component.ts)
<div class="grid"> <div class="row"> <div class="col-xs-4"> <ng-content select="[grid-item-index=0]"></ng-content> </div> <div class="col-xs-4"> <ng-content select="[grid-item-index=1]"></ng-content> </div> <div class="col-xs-4"> <ng-content select="[grid-item-index=2]"></ng-content> </div> </div> <div class="row"> <div class="col-xs-4"> <ng-content select="[grid-item-index=3]"></ng-content> </div> <div class="col-xs-4"> <ng-content select="[grid-item-index=4]"></ng-content> </div> <div class="col-xs-4"> <ng-content select="[grid-item-index=5]"></ng-content> </div> </div> </div> And this is part of the parent component that uses it.
parent template
<grid> <div *ngFor="let item of items; index as i" [attr.grid-item-index]="i"> <span>{{item}}</span> </div> </grid> Here's a Plunker.
But the result displays no content. But using...
<grid> <div grid-item-index="0">item 0</div> <div grid-item-index="1">item 1</div> <div grid-item-index="2">item 2</div> <div grid-item-index="3">item 3</div> <div grid-item-index="4">item 4</div> <div grid-item-index="5">item 5</div> </grid> it works fine and the result was as I expected.
A Plunker of this last working case.
Can achieve this result using a ngfor or similar.
I've tried using nth-child css pseudo class to avoid using the index but it doesn't work too.
UPDATE
I've made some progress based on @yurzui (Thanks!!) answer. It allows to map content with an grid-item-index value to the view container with the same grid-item-index value.
parent.component.html
<grid> <ng-template *ngFor="let item of items; let i=index" [grid-item-index]="(items.length-1)-i"> <span >{{item}}</span> </ng-template> </grid> grid-item-index directive
@Directive({ selector: '[grid-item-index]' }) export class GridItemIndexDirective { @Input('grid-item-index') index: any; constructor(public vcRef: ViewContainerRef, public tRef: TemplateRef) {} } grid.component.ts
@ContentChildren(GridItemIndexDirective) sources: QueryList<GridItemIndexDirective>; @ViewChildren(GridItemIndexDirective) containers: QueryList<GridItemIndexDirective>; constructor( private cdRef:ChangeDetectorRef ) {} ngAfterViewInit() { const len = this.sources.length; for (var i = 0; i < len; i++) { const destinationContainer = this.containers.find(x => x.index == i); const source = this.sources.find(x => x.index == i); if (destinationContainer) { destinationContainer.vcRef.createEmbeddedView(source.tRef); this.cdRef.detectChanges(); // this solves ExpressionChangedAfterItHasBeenCheckedError } } } Check this Plunker
template="is deprecated then plnkr.co/edit/GzaFRu2T8vKqyPdEkBjv?p=preview