Wprowadzenie
W Angular 8 ngSwitch jest dyrektywą strukturalną, która jest używana do dodawania/usuwania elementów drzewa DOM. Jest podobna do tej samej instrukcji(switch) w języku C#. Podobna jest również zasada działania – przełączanie odbywa się na podstawie zdefiniowanego wyrażenia.
Składania przedstawia się następująco:
<selector [ngSwitch]="wyrażenie">
<selektor_wewnetrzny *ngSwitchCase="pasujace_wyrazenie_1">…</selektor_wewnetrzny>
<selektor_wewnetrzny *ngSwitchCase="pasujace_wyrazenie_2">…</selektor_wewnetrzny>
<selektor_wewnetrzny *ngSwitchCase="pasujace_wyrazenie_3">…</selektor_wewnetrzny>
<selektor_wewnetrzny *ngSwitchDefault>…</selektor_wewnetrzny>
</selector>
ngSwitchCase oraz ngSwitchDefault
Dyrektywa ngSwitchCase umieszczana jest w elemencie wewnętrznym kontenera i pozwala na przygotowania wyrażenia będącego dopasowaniem do warunku. Za każdym razem gdy dojdzie do spełnia warunku dany element wewnętrzny zostanie dodany do drzewa DOM. Wszystkie pozostałe elementy zostaną usunięte z DOM.
W Angular 8 możemy również posługiwać się dyrektywą ngSwitchDefault. Element taki zostanie wyświetlony tylko wtedy, gdy nie zostanie znalezione żadne dopasowanie. Element ten może zostać umieszczony w dowolnym miejscu wewnątrz kontenera – nie musi być to element ostatni. W naszym zapisie może pojawić się więcej elementów domyślnych – wówczas, kiedy nie dojdzie do pasowania, każdy z nich zostanie wyświetlony.
Warto również wspomnieć, że w kontenerze poza elementami ngSwitchCase oraz ngSwitchDefault możemy zdefiniować inne elementy – zostane one wyświetlone w niezmienionej postaci.
Przykłady
Zmieniamy operatory logiczne w projekcie, który przygotowaliśmy we wpisie Angular 8: dyrektywa ngIf. Tak powinien wyglądać ekran główny przed przejściem dalej:
Następnie do naszego komponentu dodamy poniższy kod stanowiący definicję kolekcji oraz wartość wyrażenia dopasowania:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-ng-switch',
templateUrl: './ng-switch.component.html',
styleUrls: ['./ng-switch.component.css']
})
export class NgSwitchComponent implements OnInit {
title: string;
isTimeForThisComponent: boolean;
cars: Cars[];
selectedCar: number;
constructor() {
this.isTimeForThisComponent = true;
if (this.isTimeForThisComponent){
this.title = 'Tematem tego wpisu jest dyrektywa ng-switch';
} else {
this.title = 'Temat tego wpisu nie dotyczy dyrektywy ng-switch';
}
this.cars = [
{id: 1, name: 'Audi RS6 C7'},
{id: 2, name: 'Pagani Zonda F Roadster'},
{id: 3, name: 'Nissan GTR R34'}
];
this.selectedCar = 1;
}
ngOnInit() {
}
}
class Cars {
id: number;
name: string;
}
Celem naszego prostego projektu będzie wybieranie z listy rozwijalnej dostępnych modeli samochodów a dyrektywę ngSwitch wykorzystamy do wyświetlenia przykładowego zdjęcia wybranego samochodu. Implementacja może wyglądać w poniższy sposób:
<p *ngIf="isTimeForThisComponent" class="article-subject">
{{title}}
</p>
<p *ngIf="!isTimeForThisComponent" class="not-article-subject">
{{title}}
</p>
<div id="switch-test-container" *ngIf="isTimeForThisComponent"
style="width:860px;margin-left: auto;margin-right: auto;">
<!-- [(ngModel)] - dwukierunkowe wiązanie -> w kolejnych wpisie omówimy bardziej szczegółowo -->
<select [(ngModel)]="selectedCar">
<!-- Wykorzystujemy dyrektywę ngFor celem dodania elementów do wybrania -->
<option *ngFor="let car of cars;" [value]="car.id">{{car.name}}</option>
</select>
<!-- Dyrektywę ngSwitch używamy do wyświetlenia odpowiedniego zdjęcia samochodu -->
<div id="car-images" [ngSwitch]="selectedCar">
<div *ngSwitchCase="1">
<img width="100%"
src="https://image.shutterstock.com/z/stock-photo-audi-rs-avant-c-in-motion-kiev-ukraine-june-editorial-photo-662321233.jpg">
</div>
<div *ngSwitchCase="2">
<img width="100%"
src="https://image.shutterstock.com/z/stock-photo-pagani-sport-car-at-dreamcars-asia-expo-malaysia-637009.jpg">
</div>
<div *ngSwitchCase="3">
<img width="100%"
src="https://image.shutterstock.com/z/stock-photo-hakone-japan-november-nissan-skyline-gtr-vspec-bnr-cruising-famous-hakone-1505614688.jpg">
</div>
<div *ngSwitchDefault>
<img width="100%"
src="https://image.shutterstock.com/z/stock-photo-mortgage-default-stamp-depicting-home-loan-overdue-or-shortfall-failure-to-pay-off-line-of-credit-1362477851.jpg">
</div>
</div>
</div>
Zanim jednak pójdziemy dalej musimy skupić się na na wiązaniu dwukierunkowym. Aby uniknać błędów kompilacji musimy dokonać importu jednego pakietu, który pozwala na użycie poniższego zapisu:
<!-- [(ngModel)] - dwukierunkowe wiązanie -> w kolejnych wpisie omówimy bardziej szczegółowo -->
<select [(ngModel)]="selectedCar">
<!-- Wykorzystujemy dyrektywę ngFor celem dodania elementów do listy rozwijalnej -->
<option *ngFor="let car of cars;" [value]="car.id">{{car.name}}</option>
</select>
W tym celu nieznacznie zmodyfikujemy plik app.module.ts (spójrzcie na komentarze w kodzie):
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { DashboardComponent } from './Dashboard/dashboard.component';
import { NgIfComponent } from './components/ng-if/ng-if.component';
import { NgSwitchComponent } from './components/ng-switch/ng-switch.component';
import { NgForComponent } from './components/ng-for/ng-for.component';
// Musimy zaimportować pakiet FormsModule aby uzywać dwukierunkowego wiązania - o tym będzie więcej w kolejnym wpisie
// Poniższy zapis w pliku: ng-switch.component.html -> <select [(ngModel)]="selectedCar">
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
DashboardComponent,
NgIfComponent,
NgSwitchComponent,
NgForComponent
],
imports: [
BrowserModule,
AppRoutingModule,
// Dodany pakiet
FormsModule
],
providers: [],
bootstrap: [DashboardComponent]
})
export class AppModule { }
A tak prezentuje się działająca aplikacja: