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