Angular - dyrektywy strukturalne ngIf, ngFor i ngSwitch

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 3653 razy

Wstęp

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:

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:

<button type="button" (click)="switchToggle()">Przełącz</button> <div *ngIf="toggle else enabled">Włączny widok</div> <ng-template #enabled>Wyłączony widok</ng-template>

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

<div [ngSwitch]="value"> <div *ngSwitchCase="0">Wartość 0</div> <div *ngSwitchCase="1">Wartość 1</div> <div *ngSwitchCase="2">Wartość 2</div> </div> <button type="button" (click)="changeValue()">Przełącz zmienną sterującą value = {{ value }}</button>

Natomiast w klasie komponentu potrzebne jest jeszcze pole o nazwie value i metoda przełączająca wartość tego pola:

value: number = 1; changeValue() { this.value = (this.value + 1) % 3; }

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

<div _ngcontent-eyy-c3="" ng-reflect-ng-switch="0"><!--bindings={ "ng-reflect-ng-switch-case": "0" }--><div _ngcontent-eyy-c3="">Wartość 0</div><!--bindings={ "ng-reflect-ng-switch-case": "1" }--><!--bindings={ "ng-reflect-ng-switch-case": "2" }--></div>

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:

export interface Car{ brand: string; maxSpeed: number; acceleration: number; power: number; }

Natomiast w kodzie klasy potrzebne są pola, przechowujące tytuły nagłówka tabeli oraz jej dane:

tableHeaderTitles: string[] = [ 'Marka samochodu', 'V Max [km/h]', 'Przyspieszenie w s od 0 do 100 km/h', 'Moc KM']; cars: Car[] = [ { brand: 'Ford Mustang', maxSpeed: 250, acceleration: 6.5, power: 250 }, { brand: 'Ford T', maxSpeed: 30, acceleration: null, power: 30 }, { brand: 'Ferrari F50', maxSpeed: 325, acceleration: 3.7, power: 520 } ];

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 samochoduV Max [km/h]Przyspieszenie w s od 0 do 100 km/hMoc KM
Ford Mustang2506.5250 [KM]
Ford T3030 [KM]
Ferrari F503253.7520 [KM]

Dyrektywa ngFor umożliwia również dostęp do kilku przydatnych zmiennych takich jak:

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>

Zaś w kodzie klasy komponentu:

tableHeaderTitles: string[] = [ 'Nr.', 'Marka samochodu', 'V Max [km/h]', 'Przyspieszenie w s od 0 do 100 km/h', 'Moc KM']; cars: Car[] = [ { brand: 'Ford Mustang', maxSpeed: 250, acceleration: 6.5, power: 250 }, { brand: 'Ford T', maxSpeed: 30, acceleration: null, power: 30 }, { brand: 'Ferrari F50', maxSpeed: 325, acceleration: 3.7, power: 520 } ];

Dyrektywa ngClass umożliwia przełączanie klas styli w zależności od zmiennych odd i even.

Nr.Marka samochoduV Max [km/h]Przyspieszenie w s od 0 do 100 km/hMoc KM
1Ford Mustang2506.5250 [KM]
2Ford T3030 [KM]
3Ferrari F503253.7520 [KM]
Propozycje książek