Wprowadzenie

Dyrektywa *ngFor pozwala na powtarzanie części szablonu HTML zgodnie z iterowaną kolekcją. Poza standardowym iterowaniem przez listę elementów możemy również posłużyć się zmiennymi lokalnymi takimi jak: Index, First, Last, odd czy even - są one eksportowane przez dyrektywę.

Podstawowa składnia prezentuje się w poniższy sposób:

<li *ngFor="let element of kolekcja;">...</li>

Przykłady

Użyjemy projektu przygotowanego w poprzednim wpisie: Angular 8: dyrektywa ngIf

Zmienimy również wartości logiczne celem renderowania odpowiedniego komponentu naszego projektu. Przygotujemy prostą kolekcję zawierającą w sobie listę kilku samochodów a następnie użyjemy dyrektywy w celu przygotowania prostej tabeli. Tak może wyglądać przykładowa implementacja klasy komponentu ng-for.component.ts:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-ng-for',
  templateUrl: './ng-for.component.html',
  styleUrls: ['./ng-for.component.css']
})


export class NgForComponent implements OnInit {  
  title: string;
  isTimeForThisComponent: boolean;
  cars: Cars[];

  constructor() { 
    this.isTimeForThisComponent = true;

    if (this.isTimeForThisComponent){
      this.title = 'Tematem tego wpisu jest dyrektywa ng-for';
    } else {
      this.title = 'Temat tego wpisu nie dotyczy dyrektywy ng-for';
    }

    //#region 
    this.cars = [
      {brand: 'Audi', model: 'RS6', price: 729000, horsepower: 720},
      {brand: 'Pagani', model: 'Zonda F Roadster', price: 4200000, horsepower: 650},
      {brand: 'Audi', model: 'S8', price: 364800, horsepower: 605},
      {brand: 'McLaren Mercedes', model: 'SLR', price: 2400000, horsepower: 722},
    ]
    //#endregion
  }
  
  ngOnInit() {
  }
}

// Klasa określającą właściwości naszego obiektu
class Cars {
  brand: string;
  model: string;
  price: number;
  horsepower: number;
}

Kod po stronie HTML wraz z użytą dyrektywą:

<div *ngIf="isTimeForThisComponent" class="article-subject">
    <p>{{title}}</p>

    <table>
        <thead>
            <tr>
                <th>Marka</th>
                <th>Model</th>
                <th>Cena</th>
                <th>Moc</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let car of cars;">
                <td>{{car.brand}}</td>
                <td>{{car.model}}</td>
                <td>{{car.price}}</td>
                <td>{{car.horsepower}}</td>
            </tr>
        </tbody>
    </table>
</div>

<div *ngIf="!isTimeForThisComponent" class="not-article-subject">
    <p>{{title}}</p>
</div>
    

Oraz efekt uruchomienia aplikacji (w tym wpisie nie dodawałem żadnych styli CSS): OPIS

To jednak nie koniec naszej implementacji. We wprowadzeniu wspomniałem o różnych zmiennych, których możemy używać. Zaczniemy od zaznaczenia wierszy parzystych oraz nieparzystych innymi kolorami. Nieznacznie zmodyfikujemy użycie pętli:

<tbody>
<tr *ngFor="let car of cars; let even = even; let odd = odd"
    [ngClass]="{odd: odd, even: even}">
<td>{{car.brand}}</td>
<td>{{car.model}}</td>
<td>{{car.price}}</td>
<td>{{car.horsepower}}</td>
    </tr>
</tbody>
Oraz dodamy definicje klas do pliku ng-for.component.css:
.even {
    background-color:gray;
    color:black;
}

.odd {
    background-color: white;
    color:black;
}
Tak wygląda teraz nasza aplikacja: OPIS

Wprowadzimy jeszcze jedną modyfikację celem zaznaczenia pierwszego i ostatniego elementu na naszej liście. Ponownie, drobna modyfikacja:

<tbody>
<!-- Wprowadziłem inne nazwy klas celem pokazania sposobu dopasowania ich do naszych potrzeb -->
<tr *ngFor="let car of cars; let firstElement = first; let lastElement = last"
    [ngClass]="{firstElement: firstElement, lastElement: lastElement}">
<td>{{car.brand}}</td>
<td>{{car.model}}</td>
<td>{{car.price}}</td>
<td>{{car.horsepower}}</td>
    </tr>
</tbody>
Tak wygląda teraz nasza tabela (zmieniłem wcześniej nazwy klas w pliku CSS celem dopasowania do powyższych zmian): OPIS