Dyrektywy strukturalne służą do sterowania wyglądem widoku strony. Każda taka dyrektywa wyróżnia się znacznikiem * wstawianym przed jej nazwą. Ważne jest aby pamiętać, że Angular umożliwia nałożenie na jeden element HTML tylko jednej dyrektywy strukturalnej. Dostępne dyrektywy strukturalne to:
ngIf - steruje elementem drzewa DOM usuwając lub dodając element gdy dany warunek jest spełniony;
ngSwitch - przełącza widoki ale nie usuwa z kodu strony elementu przełączanego a jedynie go wykomentowuje;
ngFor - steruje elementem drzewa DOM poprzez iterowanie przez tablicę obiektów
Dyrektywa ngIf
Jak już wspominałem dyrektywa ngIf usuwa lub dodaje dany element do drzewa DOM. Sposób jej użycia można zobaczyć poniżej:
W powyższym kodzie ostatni element HTML ma znacznik #enabled, który oznacza zmienną podpiętą pod ten konkretny element drzewa DOM, za pomocą której można się do tego elementu z poziomu kodu HTML odwoływać. Zmienna ta została wykorzystana w dyrektywie ngIf do przełączania widoku.
Namiastka tego, jak by to działało przynajmniej wizualnie pokazana została poniżej. Należy jednak mieć na uwadze, że poniższy efekt został uzyskany przy wykorzystaniu czystego JavaScript-u.
Dla porównania kod generujący powyższy przykład z wykorzystaniem JavaScript-u wygląda tak:
<button id="toggleButton">Przełącz</button>
<div id="addElementView">
</div>
<script>
let toggle = false;
function switchToggle() {
toggle = !toggle;
let view = document.querySelector('#addElementView');
view.innerHTML = '';
let element = document.createElement('div');
element.innerText = toggle ? 'Włączony widok' : 'Wyłączony widok';
view.appendChild(element);
}
switchToggle();
document.querySelector('#toggleButton').addEventListener('click', switchToggle);
</script>
Dyrektywa ngSwitch
Dyrektywa ngSwitch pozwala na przełączanie wyświetlanych elementów. Oto przykład kodu HTML wykorzystującego tę dyrektywę:
Ważne jest, aby zdawać sobie sprawę, że ta dyrektywa nie usuwa elementów z drzewa DOM a jedynie je wykomentowuje. Oto jak wygląda kod HTML elementów sterowanych przez tą dyrektywę:
Jak widać kod ten wykomentowuje te elementy, dla których wartość warunkowa nie została spełniona.
Dyrektywa ngFor
Ostatnia dyrektywa daje możliwość wstawiania w kodzie elementów np. tablicy wartości, które mogą być obiektami lub zwykłymi wartościami liczbowymi. Oto jak w łatwy sposób można wypisywać elementy zapisane w zmiennej tablicowej wewnątrz kodu HTML komponentu z wykorzystaniem dyrektywy ngFor:
<table>
<tr>
<th *ngFor="let title of tableHeaderTitles">{{ title }}</th>
</tr>
<tr *ngFor="let car of cars">
<td>{{ car.brand }}</td>
<td>{{ car.maxSpeed }}</td>
<td>{{ car.acceleration }}</td>
<td>{{ car.power}} [KM]</td>
</tr>
</table>
W kodzie klasy komponentu potrzebny będzie interfejs do przechowywania obiektów samochodu:
Przybliżony wynik działania takiego kodu można zobaczyć poniżej (formatowanie pozostawiłem nie ruszone dając do zrozumienia, że tablica w ten sposób wygenerowana wymaga jeszcze dopracowania przy pomocy styli).
Marka samochodu
V Max [km/h]
Przyspieszenie w s od 0 do 100 km/h
Moc KM
Ford Mustang
250
6.5
250 [KM]
Ford T
30
30 [KM]
Ferrari F50
325
3.7
520 [KM]
Dyrektywa ngFor umożliwia również dostęp do kilku przydatnych zmiennych takich jak:
index - indeks elementu;
even - zmienna typu boolean zawierająca true gdy indeks rekordu jest liczbą parzystą;
odd -zmienna typu boolean zawierająca true gdy indeks rekordu jest liczbą nieparzystą;
first - zmienna przechowująca pierwszy rekord danych;
last - zmienna przechowująca ostatni rekord danych;
trackBy - parametr, do którego można przypisać funkcję, która zoptymalizuje odświeżanie danych w tabeli poprzez wykrywanie zmiany np. po id
Prosty przykład kodu, który wykorzystuje część powyżej wymienionych zmiennych wygląda w HTML-u tak:
<table>
<tr>
<th *ngFor="let title of tableHeaderTitles">{{ title }}</th>
</tr>
<tr *ngFor="let car of cars; let i = index; let even = even; let odd = odd" [ngClass]="{ 'odd': odd, 'even': even }">
<td>{{ i + 1 }}</td>
<td>{{ car.brand }}</td>
<td>{{ car.maxSpeed }}</td>
<td>{{ car.acceleration }}</td>
<td>{{ car.power}} [KM]</td>
</tr>
</table>