Многократная передача через ngFor в Angular2

Я довольно новичок в angular2, и я пытаюсь сделать небольшой угловой компонент под названием"решетки", что просто переставляет ее содержимого с помощью передача.

шаблона

шаблон компонента сетки (Сетка.деталь.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>

и это часть родительского компонента, который его использует.

родительского шаблона

<grid>
  <div *ngFor="let item of items; index as i" [attr.grid-item-index]="i">
    <span>{{item}}</span>
  </div>
</grid>

здесь Plunker.

но результат не отображается содержание. Но использовать...

<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>

он работает нормально, и результат был таким, как я ожидал.

A Plunker этого последнего рабочего случая.

может достичь этого результата с помощью ngfor или аналогичного.

Я попытался использовать nth-child CSS псевдо-класс, чтобы избежать использования индекса, но он тоже не работает.

обновление

Я сделал некоторый прогресс на основе @yurzui (спасибо!!) ответ. Это позволяет сопоставлять контент с решетки-элемент-индекс значение для контейнера представления с тем же решетки-элемент-индекс значение.

родитель.деталь.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({
  selector: '[grid-item-index]'
})
export class GridItemIndexDirective {
  @Input('grid-item-index') index: any;

  constructor(public vcRef: ViewContainerRef, public tRef: TemplateRef) {}
}

решетки.деталь.ТС

@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
      }
    }
  }

проверить это Plunker

1 ответов


можно использовать ngTemplateOutlet для достижения этого, но есть другой подход, который использует низкоуровневый API:

родитель.деталь.HTML-код

<grid>
  <div *ngFor="let item of items">
    <span>{{item}}</span>
  </div>
</grid>

дополнительная директива, которая поможет нам распознать индекс назначения.

@Directive({
  selector: '[grid-item-index]'
})
export class GridItemIndexDirective {
  @Input('grid-item-index') index: any;

  constructor(public vcRef: ViewContainerRef) {}
}

решетки.деталь.HTML-код

<div class="grid">
  <div class="row">
    <div class="col-xs-4">
      <ng-template grid-item-index="1"></ng-template>
    </div>
    <div class="col-xs-4">
      <ng-template grid-item-index="2"></ng-template>
    </div>
    <div class="col-xs-4">
      <ng-template grid-item-index="3"></ng-template>
    </div>
  </div>
  <div class="row">
    <div class="col-xs-4">
      <ng-template grid-item-index="4"></ng-template>
    </div>
    <div class="col-xs-4">
      <ng-template grid-item-index="5"></ng-template>
    </div>
    <div class="col-xs-4">
      <ng-template grid-item-index="6"></ng-template>
    </div>
  </div>
</div>

решетки.деталь.ТС

@ContentChild(TemplateRef, { read: ViewContainerRef }) vcRef: ViewContainerRef;
@ViewChildren(GridItemIndexDirective) containers: QueryList<GridItemIndexDirective>;

ngAfterViewInit() {
  const len = this.vcRef.length;
  for( var i = 1; i <= len; i++) {
    const destinationContainer = this.containers.find(x => x.index == i);
    if(destinationContainer) {
      const view = this.vcRef.detach(0);
      destinationContainer.vcRef.insert(view);
    }
  }
}

Пример Plunker